Pulling random string from predefined strings in qbasic - string

So i am making a random map generator in QBasic for Battlefield 3.
The idea is, whenether i run the program, the program should print a map name from already predefined strings. The code i have so far is:
CLS
REM --------------------- RANDOM NUMBER VALUE --------------------------
RANDOMIZE TIMER: A = INT((RND * 100)): B = INT((RND * 10)): C = (A + B)
NUM = INT(C - (RND * 10))
REM --------------------------- MAPS - -------------------------------
A$ = "Caspian Border"
B$ = "Damavant Peak"
C$ = "Grand Bazaar"
D$ = "Kharg Island"
E$ = "Norshar Canals"
F$ = "Operation Firestorm"
G$ = "Operation Metro"
H$ = "Seine Corssing"
I$ = "Tehran Highway"
REM ----------------------------- GAME MODE ----------------------------
RSH$ = "Rush"
TDM$ = "Team Deathmatch"
CQS$ = "Conquest"
CQSL$ = "Conquest Large"
SQDM$ = "Squad Deathmatch"
REM --------------------------- PLAYER COUNT -----------------------------
AA$ = "16 Players"
BB$ = "32 Players"
CC$ = "64 Players"
REM ------------------------ PROCESSING CODE ----------------------------
PRINT "Bore-o-mat 3000 Initilaized"
PRINT "The random number is"; NUM; "therfore the map drawn is:"
IF NUM > 10 THEN PRINT A$
IF NUM > 20 THEN PRINT B$
IF NUM > 30 THEN PRINT C$
IF NUM > 40 THEN PRINT D$
IF NUM > 50 THEN PRINT E$
IF NUM > 60 THEN PRINT F$
IF NUM > 70 THEN PRINT G$
IF NUM > 80 THEN PRINT H$
IF NUM > 90 THEN PRINT I$
END
Lets say the random NUM is 22.
It checks if NUM is bigger than 10 and prints A$, because 22 > 10. It does the same for B$. When it comes to C$, the program breaks as NUM is not > 30. Thats normal. The problem is that i get more than one map name. I get a few. Reffer to the picture:
http://i.stack.imgur.com/TTnXQ.png
I want only one string based of the random number.
How do i break the code from going to the next line?
Is there a simpler way of pulling random strings?
Like i run the program and it pulls a random string out of the A$, B$, C$ etc.
Cheers :)

You should really put the strings in an array. Otherwise, here's a quick fix.
IF NUM >= 10 AND NUM < 20 THEN PRINT A$
IF NUM >= 20 AND NUM < 30 THEN PRINT B$
IF NUM >= 30 AND NUM < 40 THEN PRINT C$
IF NUM >= 40 AND NUM < 50 THEN PRINT D$
IF NUM >= 50 AND NUM < 60 THEN PRINT E$
IF NUM >= 60 AND NUM < 70 THEN PRINT F$
IF NUM >= 70 AND NUM < 80 THEN PRINT G$
IF NUM >= 80 AND NUM < 90 THEN PRINT H$
IF NUM >= 90 AND NUM < 100 THEN PRINT I$

You could place them into an array and then select one randomly:
A$(1) = "Caspian Border"
A$(2) = "Damavant Peak"
A$(3) = "Grand Bazaar"
A$(4) = "Kharg Island"
A$(5) = "Norshar Canals"
A$(6) = "Operation Firestorm"
A$(7) = "Operation Metro"
A$(8) = "Seine Corssing"
A$(9) = "Tehran Highway"
Num = INT(RND * 9 + 1)
PRINT A$(Num)

Related

Signed float to hexadecimal number

How to convert float to a specific format in hexadecimal:
1 bit for sign, 15 bit for the integer value, and the rest 16 bits for values after the decimal point.
Example output should be ffff587a for -0.6543861, fff31a35 for -12.897631, 006bde10 for 107.8674316, 003bd030 for 59.8132324
I have written a program that can do the unsigned conversion, I am stuck at the signed part. Could anyone guide me on how I can achieve this in a very compact way?
def convert(num):
binary2 = ""
Int = int(num)
fract = num - Int
binary = '{:16b}'.format(Int & 0b1111111111111111)
for i in range (16):
fract *= 2
fract_bit = int(fract)
if fract_bit == 1:
fract -= fract_bit
binary2 += '1'
else:
binary2 += '0'
return int(binary + binary2, 2)
value = 107.867431640625
x = convert(value)
hex(x)
output: 0x6bde10
This is simply the Q16.16 fixed-point format. To convert a floating-point number to this format, simply multiply it by 216 (in Python, 1<<16 or 65536) and convert the product to an integer:
y = int(x * (1<<16))
To show its 32-bit two’s complement representation, add 232 if it is negative and then convert it to hexadecimal:
y = hex(y + (1<<32 if y < 0 else 0))
For example, the following prints “0xfff31a35”:
#!/usr/bin/python
x=-12.897631
y = int(x * (1<<16))
y = hex(y + (1<<32 if y < 0 else 0))
print(y)
This conversion truncates. If you want rounding, you can add .5 inside the int or you can add additional code for other types of rounding. You may also want to add code to handle overflows.

Loop optimization in QB64

Have a loop in QB64 concerning loop optimization:
DIM N AS DOUBLE, X(100000000) AS DOUBLE
T! = TIMER
FOR N = 1 to 100000000
IF X(N) THEN
PRINT X(N)
EXIT FOR
END IF
NEXT
PRINT TIMER - T!
is it any faster than:
DIM N AS DOUBLE, X(100000000) AS DOUBLE
T! = TIMER
FOR N = 1 to 100000000
IF X(N) <> 0 THEN
PRINT X(N)
EXIT FOR
END IF
NEXT
PRINT TIMER - T!
EDITED: 09-18-2018 to include variable types
I written this code to evaluate your test:
REM Delete REM to enable console runs
REM $CONSOLE:ONLY
REM _DEST _CONSOLE
DIM SHARED N AS DOUBLE, X(100000000) AS DOUBLE
S# = 0: ZC% = 0
T% = 10
IF COMMAND$ <> "" THEN
T% = VAL(COMMAND$)
END IF
IF T% > 999 THEN T% = 999
FOR I% = 1 TO T%
A# = TRYA
B# = TRYB
D# = A# - B#
PRINT USING "Case A ... : #.########"; A#
PRINT USING "Case B ... : #.########"; B#
PRINT USING "Diff ..... : #.########"; D#;
A$ = ""
IF ABS(D#) < 0.00000001 THEN
ZC% = ZC% + 1
A$ = "*"
END IF
S# = S# + A# - B#
PRINT A$
PRINT
REM INKEY$ doesn't work in console mode!
A$ = INKEY$
IF A$ = CHR$(27) THEN
I% = I% + 1: EXIT FOR
END IF
NEXT
PRINT USING "Avrg A - B : #.########"; S# / (I% - 1)
PRINT USING "0 diff:### on ### tryes"; ZC%, (I% - 1)
PRINT
PRINT "Hit a key to exit!"
REM INPUT$ doesn't work in console mode!
A$ = INPUT$(1)
SYSTEM
FUNCTION TRYA#
T# = TIMER
FOR N = 1 TO 100000000
IF X(N) THEN
PRINT X(N)
EXIT FOR
END IF
NEXT
A# = TIMER - T#
TRYA = A#
END FUNCTION
FUNCTION TRYB#
T# = TIMER
FOR N = 1 TO 100000000
IF X(N) <> 0 THEN
PRINT X(N)
EXIT FOR
END IF
NEXT
A# = TIMER - T#
TRYB = A#
END FUNCTION
The two different routines are inserted into two functions: TRYA and TRYB.
I launched this SW with a loop that runs 999 times the functions and the result is:
Avrg. A - B: 0.00204501
0 diff:359 on 999 tryes
then I launched with a 10 times loop and the result is:
Avrg. A - B: -.01640625
0 diff: 1 on 10 tryes
then I launched with a 15 times loop and the result is:
Avrg. A - B: 0.00026042
0 diff: 5 on 15 tryes
Cause we launch the SW in a multi-thread ambient I don't believe this is a very good test, but there's some results:
In two cases the results of no difference (0 diff) is a third of all loops.
In two cases it seems the function TRYA is slower.
In one case it seems the function TRYB is slower.
Looking at these results, I think, we may consider the two functions equivalent!
You obtain more than 10 loops running the code from command line (or modifying the command$ parameter into the QB64 menu) as:
# ./test n
Where n is the number of loops you desire.
The SW was compiled using gcc with -O3 optimizations option. (To do this you have to modify the file [/opt/]qb64/internal/c/makeline_lnx.txt)

Getting all strings in a lua script

I'm trying to encode some strings in my lua script, and since that I have a lua script with over 200k characters, encrypting each string query in the script with a function such as this example below
local string = "stackoverflow"
local string = [[stackoverflow]]
local string = [==[stackoverflow]==]
local string = 'stackoverflow'
to
local string=decode("jkrtbfmviwcfn",519211)
Trying to provide all above results to thread through a gsub and have the gsub encode the string text with a random offset number.
So far, I was only capable of gsubbing full quotation marks through.
function encode(x,offset,a)
for char in string.gmatch(x, "%a") do
local encrypted = string.byte(char) + offset
while encrypted > 122 do
encrypted = encrypted - 26
end
while encrypted < 97 do
encrypted = encrypted + 26
end
a[#a+1] = string.char(encrypted)
end
return table.concat(a)
end
luacode=[==[thatstring.Value="Encryptme!" testvalue.Value=[[string with
a linebreak]] string.Text="STOP!"]==]
luacode=luacode:gsub([=["(.-)"]=],function(s)
print("Caught "..s)
local offset=math.random(1,4)
local encoded=encode(s,offset,{})
return [[decode("]]..encoded..[[",]]..offset..[[)]]
end)
print("\n"..luacode)
With its output being
Caught Encryptme!
Caught STOP!
thatstring.Value=decode("crgvctxqi",4) testvalue.Value=[[string with
a linebreak]] string.Text=decode("opkl",2)
Any better solutions?
local function strings_and_comments(lua_code, callback)
-- lua_code must be valid Lua code (an error may be raised on syntax error)
-- callback will be invoked as callback(object_type, value, start_pos, end_pos)
-- callback("comment", comment_text, start_pos, end_pos) -- for comments
-- callback("string", string_value, start_pos, end_pos) -- for string literals
local objects = {} -- possible comments and string literals in the code
-- search for all start positions of comments (with false positives)
for pos, br1, eq, br2 in lua_code:gmatch"()%-%-(%-*%[?)(=*)(%[?)" do
table.insert(objects, {start_pos = pos,
terminator = br1 == "[" and br2 == "[" and "]"..eq.."]" or "\n"})
end
-- search for all start positions of string literals (with false positives)
for pos, eq in lua_code:gmatch"()%[(=*)%[[%[=]*" do
table.insert(objects, {is_string = true, start_pos = pos,
terminator = "]"..eq.."]"})
end
for pos, quote in lua_code:gmatch"()(['\"])" do
table.insert(objects, {is_string = true, start_pos = pos, quote = quote})
end
table.sort(objects, function(a, b) return a.start_pos < b.start_pos end)
local end_pos = 0
for _, object in ipairs(objects) do
local start_pos, ok, symbol = object.start_pos
if start_pos > end_pos then
if object.terminator == "\n" then
end_pos = lua_code:find("\n", start_pos + 1, true) or #lua_code
-- exclude last spaces and newline
while lua_code:sub(end_pos, end_pos):match"%s" do
end_pos = end_pos - 1
end
elseif object.terminator then
ok, end_pos = lua_code:find(object.terminator, start_pos + 1, true)
assert(ok, "Not a valid Lua code")
else
end_pos = start_pos
repeat
ok, end_pos, symbol = lua_code:find("(\\?.)", end_pos + 1)
assert(ok, "Not a valid Lua code")
until symbol == object.quote
end
local value = lua_code:sub(start_pos, end_pos):gsub("^%-*%s*", "")
if object.terminator ~= "\n" then
value = assert((loadstring or load)("return "..value))()
end
callback(object.is_string and "string" or "comment", value, start_pos, end_pos)
end
end
end
local inv256
local function encode(str)
local seed = math.random(0x7FFFFFFF)
local result = '",'..seed..'))'
if not inv256 then
inv256 = {}
for M = 0, 127 do
local inv = -1
repeat inv = inv + 2
until inv * (2*M + 1) % 256 == 1
inv256[M] = inv
end
end
repeat
seed = seed * 3
until seed > 2^43
local K = 8186484168865098 + seed
result = '(decode("'..str:gsub('.',
function(m)
local L = K % 274877906944 -- 2^38
local H = (K - L) / 274877906944
local M = H % 128
m = m:byte()
local c = (m * inv256[M] - (H - M) / 128) % 256
K = L * 21271 + H + c + m
return ('%02x'):format(c)
end
)..result
return result
end
function hide_strings_in_lua_code(lua_code)
local text = { [[
local function decode(str, seed)
repeat
seed = seed * 3
until seed > 2^43
local K = 8186484168865098 + seed
return (str:gsub('%x%x',
function(c)
local L = K % 274877906944 -- 2^38
local H = (K - L) / 274877906944
local M = H % 128
c = tonumber(c, 16)
local m = (c + (H - M) / 128) * (2*M + 1) % 256
K = L * 21271 + H + c + m
return string.char(m)
end
))
end
]] }
local pos = 1
strings_and_comments(lua_code,
function (object_type, value, start_pos, end_pos)
if object_type == "string" then
table.insert(text, lua_code:sub(pos, start_pos - 1))
table.insert(text, encode(value))
pos = end_pos + 1
end
end)
table.insert(text, lua_code:sub(pos))
return table.concat(text)
end
Usage:
math.randomseed(os.time())
-- This is the program to be converted
local luacode = [===[
print"Hello world!"
print[[string with
a linebreak]]
local str1 = "stackoverflow"
local str2 = [[stackoverflow]]
local str3 = [==[stackoverflow]==]
local str4 = 'stackoverflow'
print(str1)
print(str2)
print(str3)
print(str4)
]===]
-- Conversion
print(hide_strings_in_lua_code(luacode))
Output (converted program)
local function decode(str, seed)
repeat
seed = seed * 3
until seed > 2^43
local K = 8186484168865098 + seed
return (str:gsub('%x%x',
function(c)
local L = K % 274877906944 -- 2^38
local H = (K - L) / 274877906944
local M = H % 128
c = tonumber(c, 16)
local m = (c + (H - M) / 128) * (2*M + 1) % 256
K = L * 21271 + H + c + m
return string.char(m)
end
))
end
print(decode("ef869b23b69b7fbc7f89bbe7",2686976))
print(decode("c2dc20f7061c452db49302f8a1d9317aad1009711e0984",1210253312))
local str1 = (decode("84854df4599affe9c894060431",415105024))
local str2 = (decode("a5d7db792f0b514417827f34e3",1736704000))
local str3 = (decode("6a61bcf9fd6f403ed1b4846e58",1256259584))
local str4 = (decode("cad56d9dea239514aca9c8b8e0",1030488064))
print(str1)
print(str2)
print(str3)
print(str4)
Output of output (output produced by the converted program)
Hello world!
string with
a linebreak
stackoverflow
stackoverflow
stackoverflow
stackoverflow

Modified longest common substring

Given two strings what is an efficient algorithm to find the number and length of longest common sub-strings with the sub-strings being called common if :
1) they have at-least x% characters same and at same position.
2) the start and end indexes of the sub-strings being same.
Ex :
String 1 -> abedefkhj
String 2 -> kbfdfjhlo
suppose the x% being asked is 40,then, ans is,
5 1
where 5 is the longest length and 1 is the number of sub-strings in each string satisfying the given property. Sub-String is "abede" in string 1 and "kbfdf" in string 2.
You can use smth like Levenshtein distance without deleting and inserting.
Build the table, where every element [i, j] is error for substring from position [i] to position [j].
foo(string a, string b, int x):
len = min(a.length, b.length)
error[0][0] = 0 if a[0] == b[0] else 1;
for (end: [1 -> len-1]):
for (start: [end -> 0]):
if a[end] == b[end]:
error[start][end] = error[start][end - 1]
else:
error[start][end] = error[start][end - 1] + 1
best_len = 0;
best_pos = 0;
for (i: [0 -> len-1]):
for (j: [i -> 0]):
len = i - j + 1
error_percent = 100 * error[i][j] / len
if (error_percent <= x and len > best_len):
best_len = len
best_pos = j
return (best_len, best_pos)

Calculate min, max, count in linux file [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a file on linux server that has data like :
a 22
a 10
a 17
a 51
a 33
b 51
b 47
c 33
I want a shell script or linux commands to find min, avg, 90%, max and count for each value in column 1.
Example:
for a min = 10, avg = 26, 90% = 33, max = 51, and count = 5.
Here a version with even the 90% percentile using gawk.
The definition of percentile is that one given by
Wikipedia and called Nearest rank.
The function round can be found here.
#!/bin/bash
gawk '
function round(x, ival, aval, fraction)
{
ival = int(x) # integer part, int() truncates
# see if fractional part
if (ival == x) # no fraction
return ival # ensure no decimals
if (x < 0) {
aval = -x # absolute value
ival = int(aval)
fraction = aval - ival
if (fraction >= .5)
return int(x) - 1 # -2.5 --> -3
else
return int(x) # -2.3 --> -2
} else {
fraction = x - ival
if (fraction >= .5)
return ival + 1
else
return ival
}
}
# the following block processes all the lines
# and populates counters and values
{
if($1 in counters) {
counters[$1]++;
} else {
counters[$1] = 1;
}
i = counters[$1];
values[$1, i] = $2;
} END {
for (c in counters) {
delete tmp;
min = values[c, 1];
max = values[c, 1];
sum = values[c, 1];
tmp[1] = values[c, 1];
for (i = 2; i <= counters[c]; i++) {
if (values[c, i] < min) min = values[c, i];
if (values[c, i] > max) max = values[c, i];
sum += values[c, i];
tmp[i] = values[c, i];
}
# The following 3 lines compute the percentile.
n = asort(tmp, tmp_sorted);
idx = round(0.9 * n + 0.5); # Nearest rank definition
percentile = tmp_sorted[idx];
# Output of the statistics for this group.
printf "for %s min = %d, avg = %f, 90 = %d,max = %d, count = %d\n", c, min, (sum / counters[c]), percentile, max, counters[c];
}
}'
To run execute:
./stats.sh < input.txt
I am assuming that the above script is named stats.sh and your input is saved in input.txt.
The output is:
for a min = 10, avg = 26.600000, 90 = 51,max = 51, count = 5
for b min = 47, avg = 49.000000, 90 = 51,max = 51, count = 2
for c min = 33, avg = 33.000000, 90 = 33,max = 33, count = 1
Here the explanation:
counters is an associative array, the key is the value in column 1
and the value is the number of values found in the input for each
value in column 1.
values is a two dimensional (value_in_column_one, counter_per_value)
array that keeps all the values grouped by value in column one.
At the end of the script the outermost loop goes trough all the values
found in column 1. The innermost for loop analyses all the values belonging
to a particular value in column 1 and it computes all the statics.
For lines starting with a, here's an awk script.
$ echo 'a 22
a 10
a 17
a 51
a 33
b 51
b 47
c 33' | awk 'BEGIN{n=0;s=0;};/^a/{n=n+1;s=s+$2;};END{print n;print s;print s/n;}'
5
133
26.6
Using awk:
awk 'NR==1{min=$1} {sum+=$2; if(min>=$2) min=$2; if(max<$2) max=$2}
END{printf("max=%d,min=%d,count=%d,avg=%.2f\n", max, min, NR, (sum/NR))}' file
max=51,min=10,count=8,avg=33.00
EDIT:
awk '$1 != v {
if (NR>1)
printf("For %s max=%d,min=%d,count=%d,avg=%.2f\n", v, max, min, k, (sum/k));
v=$1;
min=$2;
k=sum=max=0
}
{
k++;
sum+=$2;
if (min > $2)
min=$2;
if (max < $2)
max=$2
}
END {
printf("For %s max=%d,min=%d,count=%d,avg=%.2f\n", v, max, min, k, (sum/k))
}' < <(sort -n -k1,2 f)
OUTPUT:
For a max=51,min=10,count=5,avg=26.60
For b max=51,min=47,count=2,avg=49.00
For c max=33,min=33,count=1,avg=33.00

Resources