i have an sqlite database that contains a column with BLOB data.
these BLOB data are 4 byte width. i want to split the 4 bytes appart and convert each part to an integer value to calculate with it.
i found out, that i can use SUBSTR(val, start, length) to take the BLOB value appart. the result is still of type BLOB.
but how can i convert the BLOB/byte to an integer value?
is there a built-in function that can convert byte BLOB values to an integer?
or is there a way to convert a hex-string-value into an integer value, so i could play with HEX(val) or QUOTE(val)
CREATE TEMP TABLE IF NOT EXISTS test AS SELECT x'cafe1a7e' AS val;
SELECT (val)
, TYPEOF(val)
, HEX(val)
, QUOTE(val)
, TYPEOF(HEX(val))
, TYPEOF(QUOTE(val))
, CAST(val AS INT)
, CAST(HEX(val) AS INT)
, CAST(QUOTE(val) AS INT)
, SUBSTR(val, 1, 1)
, TYPEOF(SUBSTR(val, 1, 1))
, HEX(SUBSTR(val, 1, 1))
, HEX(SUBSTR(val, 2, 1))
, HEX(SUBSTR(val, 3, 2))
, val + val
, SUBSTR(val, 1, 1) + 1
, CAST(SUBSTR(val, 1, 1) AS INT)
FROM test;
DROP TABLE test;
You can convert one hex digit at a time using instr:
SELECT hex(b), n, printf("%04X", n)
FROM (SELECT b,
(instr("123456789ABCDEF", substr(hex(b), -1, 1)) << 0) |
(instr("123456789ABCDEF", substr(hex(b), -2, 1)) << 4) |
(instr("123456789ABCDEF", substr(hex(b), -3, 1)) << 8) |
(instr("123456789ABCDEF", substr(hex(b), -4, 1)) << 12) |
(instr("123456789ABCDEF", substr(hex(b), -5, 1)) << 16) |
(instr("123456789ABCDEF", substr(hex(b), -6, 1)) << 20) |
(instr("123456789ABCDEF", substr(hex(b), -7, 1)) << 24) |
(instr("123456789ABCDEF", substr(hex(b), -8, 1)) << 28) AS n
FROM (SELECT randomblob(4) AS b))
Example output:
D91F8E91|3642723985|D91F8E91
(Simplification of idea from [1].)
There is no built in function that I know of, so this is how I do it - if you know how many bytes you want to convert:
--creates table h2i with numbers 0 to 255 in hex and int
CREATE TEMP TABLE bits (bit INTEGER PRIMARY KEY);INSERT INTO bits VALUES (0);INSERT INTO bits VALUES (1);
CREATE TEMP TABLE h2i (h TEXT, i INT);
INSERT INTO h2i (h, i) SELECT printf('%02X',num),num FROM (SELECT b7.bit * 128 + b6.bit * 64 + b5.bit * 32 + b4.bit * 16 + b3.bit * 8 + b2.bit * 4 + b1.bit * 2 + b0.bit AS num FROM bits b7, bits b6, bits b5,bits b4, bits b3, bits b2, bits b1, bits b0) as nums;
SELECT
HEX(SUBSTR(val, 1, 1)),h2i0.i
,HEX(SUBSTR(val, 2, 1)),h2i1.i
,HEX(SUBSTR(val, 3, 2)),h2i2.i*256+h2i3.i
,HEX(SUBSTR(val, 1, 4)),h2i0.i*16777216+h2i1.i*65536+h2i2.i*256+h2i3.i
FROM test
JOIN h2i h2i0 ON h2i0.h=HEX(SUBSTR(val, 1, 1))
JOIN h2i h2i1 ON h2i1.h=HEX(SUBSTR(val, 2, 1))
JOIN h2i h2i2 ON h2i2.h=HEX(SUBSTR(val, 3, 1))
JOIN h2i h2i3 ON h2i3.h=HEX(SUBSTR(val, 4, 1))
;
#rayzinnz, thank you for the hint.
in the meantime i gave up.
i puzzled together a kind of a solution, but i never got it work to set the initial x'cafe1a7e' value from outside the WITH RECURSIVE construction.
WITH RECURSIVE fx(val_hex, val_int, iter) AS (
VALUES(HEX(x'cafe1a7e'), 0, 0)
UNION ALL
SELECT
SUBSTR(val_hex, 1, LENGTH(val_hex) - 1),
val_int + (
CASE SUBSTR(val_hex, -1)
WHEN '0' THEN 0
WHEN '1' THEN 1
WHEN '2' THEN 2
WHEN '3' THEN 3
WHEN '4' THEN 4
WHEN '5' THEN 5
WHEN '6' THEN 6
WHEN '7' THEN 7
WHEN '8' THEN 8
WHEN '9' THEN 9
WHEN 'A' THEN 10
WHEN 'B' THEN 11
WHEN 'C' THEN 12
WHEN 'D' THEN 13
WHEN 'E' THEN 14
WHEN 'F' THEN 15
ELSE 0
END << (iter * 4)
),
iter + 1
FROM fx
WHERE val_hex != ''
LIMIT 9
)
--SELECT * FROM fx
SELECT val_int FROM fx WHERE val_hex == ''
;
the BLOB value there is hardcoded.
maybe you find a way.
Related
I need to take data and combine to insert into an table as a menu code. The menu code takes the form LNNLLLL (L = Letter and N=Number) and it is made up of MenU Cycle (hard-coded, one off project), Week Number (1-3), Day Number (1-7 - Monday=1), MealCode, Customer Type Code (3 Letters). The following SELECT query returns exactly what I want insert. The hardcoded date is a known date from which the week number and day number can be derived ie it is a Week 1 Monday.
SELECT group_concat('C' || CASE
WHEN (CAST(julianday(mealdate) AS INT) - cast(julianday('2022-08-22') AS INT)) % 21 <= 6 THEN 1
WHEN (CAST(julianday(mealdate) AS INT) - cast(julianday('2022-08-22') AS INT)) % 21 <= 13 THEN 2
ELSE 3
END ||
CASE WHEN (CAST(julianday(mealdate) AS INT) - cast(julianday('2022-08-22') AS INT)) % 21 + 1 IN (1, 8, 15) THEN 1
WHEN (CAST(julianday(mealdate) AS INT) - cast(julianday('2022-08-22') AS INT)) % 21 + 1 IN (2, 9, 16) THEN 2
WHEN (CAST(julianday(mealdate) AS INT) - cast(julianday('2022-08-22') AS INT)) % 21 + 1 IN (3, 10, 17) THEN 3
WHEN (CAST(julianday(mealdate) AS INT) - cast(julianday('2022-08-22') AS INT)) % 21 + 1 IN (4, 11, 18) THEN 4
WHEN (CAST(julianday(mealdate) AS INT) - cast(julianday('2022-08-22') AS INT)) % 21 + 1 IN (5, 12, 19) THEN 5
WHEN (CAST(julianday(mealdate) AS INT) - cast(julianday('2022-08-22') AS INT)) % 21 + 1 IN (6, 13, 20) THEN 6
WHEN (CAST(julianday(mealdate) AS INT) - cast(julianday('2022-08-22') AS INT)) % 21 + 1 IN (7, 14, 21) THEN 7
END ||
MealCode ||
(SELECT CustTypeCodeNew FROM CustomerNew WHERE CustCodeNew LIKE SalesOrderNew.CustomerCode)) AS MenuCode
FROM SalesOrderNew
GROUP BY SalesOrderID
Here is some output from that (I've added MealDate and MealCode to the select just to give better context to the resulting MenuCode column which is the one that needs inserted.
MealDate MealCode MenuCode
2022-08-23 K C12KNRE
2022-08-23 K C12KRES
2022-08-23 K C12KSHO
2022-08-23 K C12KRES
2022-08-25 T C14TNRE
2022-08-25 T C14TRES
2022-08-25 L C14LNRE
2022-08-25 L C14LNRE
2022-08-25 T C14TNRE
The MenuCode column is currently filled with NULL values.
However if I put add a line above to INSERT INTO SalesOrderNew (MenuCode) I get this error Result: NOT NULL constraint failed: SalesOrderNew.CustomerCode. It does not seem to like the subselect that used within the group_contact. How do I go about resolving this?
I had this question in an interview but I was not able to solve it.
We have a grid of 2 rows and n columns. We have to find the number of ways to sit M men and W women given no men can sit adjacent or in front of each other.
I thought of solving it by Dynamic Programming but I'm not sure how to get the recurrence relation.
I know that if I am at (0,i), I can go to (1,i+1) but I don't know how to keep track of counts of men and women so far. Can anybody help me with the recurrence relation or states of dp?
Recurrence relation
Here is one recurrence relation I could thing of.
Let's call n_ways(N, W, M, k) the number of ways to seat:
W women
and M men
in the remaining N columns
knowing there was k men in the previous column. k can only take values 0 and 1.
n_ways(N, 0, 0, k) = 1
n_ways(N, W, M, k) = 0 if M > N or W+M > 2*N
n_ways(N, W, 0, k) = ((2*N) choose W)
n_ways(N, 0, M, 0) = 2 * (N choose M)
n_ways(N, 0, M, 1) = (N choose M)
n_ways(N, W, M, 0)
= n_ways(N-1, W, M, 0) // put nobody in first column
+ 2 * n_ways(N-1, W-1, M, 0) // put 1 woman in first column
+ n_ways(N-1, W-2, M, 0) // put 2 women in first column
+ 2 * n_ways(N-1, W-1, M-1, 1) // put 1 woman & 1 man in first column
+ 2 * n_ways(N-1, W, M-1, 1) // put 1 man in first column
n_ways(N, W, M, 1)
= n_ways(N-1, W, M, 0) // put nobody in first column
+ 2 * n_ways(N-1, W-1, M, 0) // put 1 woman in first column
+ n_ways(N-1, W-2, M, 0) // put 2 women in first column
+ n_ways(N-1, W-1, M-1, 1) // put 1 woman & 1 man in first column
+ n_ways(N-1, W, M-1, 1) // put 1 man in first column
Testing with python
Since I'm too lazy to implement dynamic programming myself, I instead opted for caching using python's functools.cache.
I implemented the recurrence relation above as a cached recursive function, and got the following results:
Number of ways to seat w women and m men in n columns:
n, w, m --> ways
0, 0, 0 --> 1
0, 0, 1 --> 0
0, 1, 0 --> 0
1, 2, 0 --> 1
1, 0, 2 --> 0
1, 1, 1 --> 2
2, 2, 2 --> 2
3, 3, 3 --> 2
4, 6, 2 --> 18
10, 15, 5 --> 2364
10, 10, 10 --> 2
Here is the python code:
from functools import cache
from math import comb
#cache
def n_ways(n, w, m, k):
if w == m == 0:
return 1
elif m > n or w + m > 2 * n:
return 0
elif m == 0:
return comb(2*n, w)
elif w == 0:
return (2-k) * comb(n, m)
else:
r_0, r_w, r_ww, r_wm, r_m = (
n_ways(n-1, w, m, 0),
n_ways(n-1, w-1, m, 0),
n_ways(n-1, w-2, m, 0) if w > 1 else 0,
n_ways(n-1, w-1, m-1, 1),
n_ways(n-1, w, m-1, 1)
)
return (r_0 + r_w + r_w + r_ww + r_wm + r_m) + (1-k) * (r_wm + r_m)
if __name__=='__main__':
print(f'Number of ways to seat w women and m men in n columns:')
print(f' n, w, m --> ways')
for w, m in [(0, 0), (0, 1), (1, 0), (2, 0), (0, 2),
(1, 1), (2, 2), (3, 3), (6, 2), (15, 5),
(10, 10)]:
n = (w + m) // 2
print(f'{n:2d}, {w:2d}, {m:2d} --> ', end='')
print(n_ways(n, w, m, 0))
I have an array containing integers from 1 to 1000. I'm trying to count how many times this equation is true A + B + C + D = E where A <= B <= C <= D and A, B, C, D, E are all items from the array. Could you guys suggest any solutions?
The array contains all integers from 1 to 1000, so 1, 2, 3, 4, .. , 999, 1000. The numbers A - D can be the same number from the array.
You need to calculate number of integer partitions for every value E in range 1..1000 into 4 parts.
Python function countparts to calculate number of such partitions.
def cp(n, k, m):
if k == 0:
if n == 0:
return 1
else:
return 0
res = 0
for i in range(min(n + 1, m + 1)):
res += cp(n - i, k - 1, i)
return res
def countparts(n, k):
return cp(n - k, k, n - k + 1)
print(countparts(8, 4))
>> 5 (1115, 1124, 1133, 1223, 2222)
But it works slowly for large arguments.
Also at this page I found formula to get needed values fast:
P(i) = round((i**3 + 3*i*i - 9*i*(i % 2))/144)
A Dutch bank account consists of 9 digits e.g.: 1334.36.915.
To check whether the bank account is valid we use the so called ‘11-proef’ (11-test).
In this test each digit is multiplied with its place in the row.The result of this multiplication is added up.
(1*9)+(3*8)+(3*7)+(4*6)+(3*5)+(6*4)+(9*3)+(1*2)+(5*1) = R
This result has to be dividable by 11. That means the remainder of the division must be 0.
If the R is dividable by 11 the bank account number is valid!
Can someone help with this question?
A Dutch bank account number does not consist of 9 digits anymore, we now use Iban Numbers. If you want to do a check on it, you should have a look at https://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN and implement that check.
For now, you can however still to the 11-check on the last 9 or 10 digits, but it's not guaranteed that will still work for new bank accounts in the future.
If you still want to do a 11-check, you can create a function like this:
CREATE OR REPLACE FUNCTION elfproof (accountnummer IN varchar2)
RETURN VARCHAR2
AS
multiplier int:= 10;
outcome varchar2(10);
total int := 0;
BEGIN
FOR i IN 1 .. 9
LOOP
multiplier := multiplier - 1;
total := total + (multiplier * TO_NUMBER (SUBSTR (accountnummer, i, 1)));
END LOOP;
IF MOD (total, 11) = 0
THEN
outcome := 'good';
ELSE
outcome := 'bad';
END IF;
return outcome;
END;
This gives the remainder of division on 11:
SELECT
MOD (SUM (TO_NUMBER (SUBSTR (str, LEVEL, 1)) * (10 - LEVEL)), 11) remdiv11
FROM
(
SELECT
REPLACE ('1334.36.915', '.') str
FROM
DUAL
) d
CONNECT BY LEVEL <= LENGTH (str)
and IBAN check;) :
SELECT
DECODE (MOD (TO_NUMBER (LISTAGG (n, '') WITHIN GROUP (ORDER BY l)), 97), 1, 'OK', 'Fail') AS iban_check
FROM
(
SELECT
TO_CHAR (CASE
WHEN ASCII (c) >= 65 THEN ASCII (c) - 55
ELSE ASCII (c) - 48 END) n, c, l
FROM
(
SELECT
SUBSTR (str, LEVEL, 1) c, LEVEL l
FROM
(
SELECT
SUBSTR (s, 5) || SUBSTR (s, 1, 4) str
FROM
(
SELECT
REPLACE ('GB82 WEST 1234 5698 7654 32', ' ') s
FROM
DUAL
)
)
CONNECT BY LEVEL <= LENGTH (str)
)
)
I have the grasp of the idea of crypt arithmetic and addition but I cannot figure out how to do a multiplication crypt arithmetic problem. It's simply TWO*SIX=TWELVE or something along those lines without the middle additional part of the multiplication problem given. I couldn't find anything online and I already found some constraints for the problem but nothing to leads me to some answers. Not sure where to ask this and thought this would be the best place.
I want to know how to solve a multiplication crypt arithmetic problem.
I already concluded:
T W O
* S I X
_________________
T W E L V E
T \= 0 which also means S \= 0
T is 1-6
E is (O*X) mod 10
O or X cannot be 0 or 1 since E has to be different and 0 or 1 gives the same value
as either O or X.
EDIT: I was using the generate and test method
solve(T,W,O,S,I,X,E,L,V) :-
X = [T,W,O,S,I,X,E,L,V],
Digits = [0,1,2,3,4,5,6,7,8,9],
assign_digits(X, Digits),
T > 0,
S > 0,
100*T + 10*W + O * 100*S + 10*I + X =:=
100000*T + 10000*W + 1000*E + 100*L + 10*V + E,
write(X).
select(X, [X|R], R).
select(X, [Y|Xs], [Y|Ys]):- select(X, Xs, Ys).
assign_digits([], _List).
assign_digits([D|Ds], List):-
select(D, List, NewList),
assign_digits(Ds, NewList).
Trivially to do with constraint logic programming. For example, in ECLiPSe Prolog:
:- lib(ic).
puzzle(Vars) :-
[T,W,O,S,I,X,E,L,V] = Vars,
Vars :: 0..9,
alldifferent(Vars),
T #> 0, S #> 0,
(100*T + 10*W + O) * (100*S + 10*I + X) #=
100000*T + 10000*W + 1000*E + 100*L + 10*V + E,
labeling(Vars).
First solution:
[eclipse]: puzzle([T,W,O,S,I,X,E,L,V]).
T = 1
W = 6
O = 5
S = 9
I = 7
X = 2
E = 0
L = 3
V = 8
Yes (0.01s cpu, solution 1, maybe more) ?
There are 3 different solutions:
[eclipse]: puzzle([T,W,O,S,I,X,E,L,V]), writeln([T,W,O,S,I,X,E,L,V]), fail.
[1, 6, 5, 9, 7, 2, 0, 3, 8]
[2, 1, 8, 9, 6, 5, 0, 3, 7]
[3, 4, 5, 9, 8, 6, 0, 1, 7]
No (0.02s cpu)
Update - translation to SWI Prolog:
:- use_module(library(clpfd)).
puzzle(Vars) :-
[T,W,O,S,I,X,E,L,V] = Vars,
Vars ins 0..9,
all_different(Vars),
T #> 0, S #> 0,
(100*T + 10*W + O) * (100*S + 10*I + X) #=
100000*T + 10000*W + 1000*E + 100*L + 10*V + E,
label(Vars).
More general and no-CLP solution:
number_to_digits(Number,List) :-
length(List,Len),
ntb(0,Len,Number,List).
ntb(N,_,N,[]).
ntb(C,E,N,[D|L]) :-
NE is E-1,
V is C + D*10^NE,
ntb(V,NE,N,L).
crypto(In1, In2, Out) :-
term_variables([In1, In2, Out], Vars),
permutation([0,1,2,3,4,5,6,7,8,9], Perm),
append(_, Vars, Perm),
number_to_digits(N1, In1),
number_to_digits(N2, In2),
number_to_digits(N3, Out),
N3 is N1 * N2.
It is quite inefficient and definetly this problem should be solved using CLP like #Sergey did, but maybe someone will be interested in possible solutions without CLP.
Input and output:
?- crypto([T,W,O], [S,I,X], [T,W,E,L,V,E]).
T = 0,
W = 5,
O = 7,
S = 9,
I = 6,
X = 2,
E = 4,
L = 8,
V = 3;
(...)
(57 * 962 = 54834).