Resource temporarily unavailable futex while strace'ing sqoop command - hadoop
I am having a sqoop command which imports data from Oracle into hive orc table using the hcatalog parameters.
sqoop import -D oraoop.disabled=true -D mapred.child.java.opts="\-Djava.security.egd=file:/dev/../dev/urandom" --connect 'jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=dbs-dev-v.com)(PORT=1533))(CONNECT_DATA=(SERVICE_NAME=SDADCOM)(Server=Dedicated)))' --username phani --password pass --query "select ITEM_ID,ROLLUP_ITEM_ID,CPI_FORMAT1,CPI_FORMAT2,CPI_FORMAT3,CA_SNO_VALID_CNTRL,CUSTOM_SERIAL_FLAG,INVENTORY_ITEM_STATUS_CODE,LAST_DOS,ESN_CAPABILITY,ROLLUP_FLAG,PRODUCT_FAMILY,PRODUCT_SUB_GROUP,ERP_ITEM_TYPE,MFG_PRODUCT_CONFIG,MFG_SERIAL_FLAG,CA_CONFIG_VALID_CNTRL,CA_INS_VALID_CNTRL,ENABLED_FLAG,CREATED_BY,CREATION_DATE,LAST_UPDATED_BY,LAST_UPDATE_DATE,IB_PRODUCT_TYPE,USER_ITEM_TYPE,ITEM_CREATION_DATE,BASE_PRODUCT_ID,PRD_CATEGORY,TECHNOLOGY_GROUP,BUSINESS_UNIT,CA_DUPL_VALID_CNTRL,SKU_LIST_PRICE,SERV_FEE_VALUE_DOLLAR_AMT,MAX_SERIALIZED_CHILD,PHYSICAL_SN_LOCATION,CPI_LINK,TOTAL_INSTANCES,TOTAL_INSTANCES_ON_CONTRACT,GP_EXCLUSION,LAST_DOA,LAST_DOR from XXCCS_SCDC_PRODUCT_PROFILE where \$CONDITIONS" --split-by ITEM_ID --incremental lastmodified --check-column ITEM_ID -m 4 --hcatalog-home /opt/mapr/hive/hive-1.2/hcatalog --hcatalog-database installbase --hcatalog-table XXCCS_SCDC_PRODUCT_PROFILE --null-string '\\N' --null-non-string '\\N' --boundary-query 'select (select min(ITEM_ID) from XXCCS_SCDC_PRODUCT_PROFILE) as minid ,(select max(ITEM_ID) from XXCCS_SCDC_PRODUCT_PROFILE) as maxid from dual' --hcatalog-storage-stanza 'stored as orc' --verbose
While executing the command i was getting the below exception
16/10/06 04:26:20 ERROR sqoop.Sqoop: Got exception running Sqoop: java.lang.NullPointerException
java.lang.NullPointerException
at com.mapr.fs.MapRFileSystem.makeAbsolute(MapRFileSystem.java:1812)
at com.mapr.fs.MapRFileSystem.getMapRFileStatus(MapRFileSystem.java:1380)
at com.mapr.fs.MapRFileSystem.getFileStatus(MapRFileSystem.java:1035)
at org.apache.hadoop.fs.FileSystem.exists(FileSystem.java:1460)
at org.apache.sqoop.tool.ImportTool.initIncrementalConstraints(ImportTool.java:320)
at org.apache.sqoop.tool.ImportTool.importTable(ImportTool.java:488)
at org.apache.sqoop.tool.ImportTool.run(ImportTool.java:606)
at org.apache.sqoop.Sqoop.run(Sqoop.java:143)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
at org.apache.sqoop.Sqoop.runSqoop(Sqoop.java:179)
at org.apache.sqoop.Sqoop.runTool(Sqoop.java:218)
at org.apache.sqoop.Sqoop.runTool(Sqoop.java:227)
at org.apache.sqoop.Sqoop.main(Sqoop.java:236)
To understand the exception i tried to tweak the code as well as configurations but everything looks good. To understand what is happening from the kernel level if there is any issues while opening a file related to the command, I did a strace on the sqoop command.
From the strace output i found that there is some resource which was unable for long time. I could not understand the output full. Can someone help me in finding the resource.
Output:
1783 stat("/opt/mapr/hadoop/hadoop-2.7.0/etc/hadoop/org/apache/hadoop/util/ShutdownHookManager$HookEntry.class", 0x7fe6fe8465b0) = -1 ENOENT (No such file or directory)
1783 lseek(93, 470334, SEEK_SET) = 470334
1783 read(93, "PK\3\4\24\0\10\0\10\0\240\254\350H\0\0\0\0\0\0\0\0\0\0\0\0:\0\0\0", 30) = 30
1783 lseek(93, 470422, SEEK_SET) = 470422
1783 read(93, "\235\222\337k\323P\24\307\2777I\233\266fv\316\375\250Z\267\316NmS0\240\342\313\234\10C\261"..., 535) = 535
1783 stat("/opt/mapr/hadoop/hadoop-2.7.0/etc/hadoop/org/apache/sqoop/tool/ImportTool$1.class", 0x7fe6fe8463f0) = -1 ENOENT (No such file or directory)
1783 stat("/opt/mapr/hadoop/hadoop-2.7.0/share/hadoop/hdfs/org/apache/sqoop/tool/ImportTool$1.class", 0x7fe6fe8463f0) = -1 ENOENT (No such file or directory)
1783 stat("/opt/mapr/sqoop/sqoop-1.4.6/conf/org/apache/sqoop/tool/ImportTool$1.class", <unfinished ...>
1806 futex(0x7fe6f80bd254, FUTEX_WAIT_PRIVATE, 529, NULL <unfinished ...>
1783 <... stat resumed> 0x7fe6fe8463f0) = -1 ENOENT (No such file or directory)
1783 stat("/users/phodisvc/org/apache/sqoop/tool/ImportTool$1.class", 0x7fe6fe8463f0) = -1 ENOENT (No such file or directory)
1783 stat("/opt/mapr/hbase/hbase-0.98.12/conf/org/apache/sqoop/tool/ImportTool$1.class", 0x7fe6fe8463f0) = -1 ENOENT (No such file or directory)
1783 stat("/opt/mapr/hbase/hbase-0.98.12/org/apache/sqoop/tool/ImportTool$1.class", 0x7fe6fe8463f0) = -1 ENOENT (No such file or directory)
1808 <... futex resumed> ) = -1 ETIMEDOUT (Connection timed out)
1808 futex(0x7fe6f80c9f28, FUTEX_WAKE_PRIVATE, 1) = 0
1808 futex(0x7fe6f80c9f54, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1, {1475851368, 803245000}, ffffffff <unfinished ...>
1783 stat("/users/phodisvc/hive/hddev-c01-edge-01/conf/org/apache/sqoop/tool/ImportTool$1.class", 0x7fe6fe8463f0) = -1 ENOENT (No such file or directory)
1783 lseek(490, 863529, SEEK_SET) = 863529
1783 read(490, "PK\3\4\n\0\0\10\10\0\364\2=HV\366~\5\17\2\0\0\227\3\0\0(\0\0\0", 30) = 30
1783 lseek(490, 863599, SEEK_SET) = 863599
1783 read(490, "\235\223\337N\23A\24\306\277i\227n[\27\273\"jA\24\204\25ZT6\30\257\324\30\rB\322\330"..., 527) = 527
1783 write(2, "16/10/07 07:42:48 DEBUG manager."..., 266) = 266
1783 write(2, "16/10/07 07:42:48 ERROR sqoop.Sq"..., 97) = 97
1783 lseek(3, 27907755, SEEK_SET) = 27907755
1783 read(3, "PK\3\4\n\0\0\0\0\0[\226\222Cq\300q\301\273\2\0\0\273\2\0\0,\0\0\0", 30) = 30
1783 lseek(3, 27907829, SEEK_SET) = 27907829
1783 read(3, "\312\376\272\276\0\0\0003\0!\1\0\6<init>\1\0\4Code\1\0\fInn"..., 699) = 699
1783 lseek(3, 27906474, SEEK_SET) = 27906474
1783 read(3, "PK\3\4\n\0\0\0\0\0[\226\222CA\333\243\260\354\1\0\0\354\1\0\0-\0\0\0", 30) = 30
1783 lseek(3, 27906549, SEEK_SET) = 27906549
1783 read(3, "\312\376\272\276\0\0\0003\0\31\1\0\3()V\1\0\6<init>\1\0\4Code"..., 492) = 492
1783 lseek(3, 59447367, SEEK_SET) = 59447367
1783 read(3, "PK\3\4\n\0\0\0\0\0`\226\222C\224Mp\244\1\7\0\0\1\7\0\0&\0\0\0", 30) = 30
1783 lseek(3, 59447435, SEEK_SET) = 59447435
1783 read(3, "\312\376\272\276\0\0\0003\0T\1\0\3()I\1\0\3()V\1\0\3()Z\1\0&("..., 1793) = 1793
1783 write(2, "java.lang.NullPointerException", 30) = 30
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat com.mapr.fs.MapRFileSystem.m"..., 69) = 69
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat com.mapr.fs.MapRFileSystem.g"..., 74) = 74
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat com.mapr.fs.MapRFileSystem.g"..., 70) = 70
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat org.apache.hadoop.fs.FileSys"..., 64) = 64
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat org.apache.sqoop.tool.Import"..., 84) = 84
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat org.apache.sqoop.tool.Import"..., 69) = 69
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat org.apache.sqoop.tool.Import"..., 61) = 61
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat org.apache.sqoop.Sqoop.run(S"..., 46) = 46
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat org.apache.hadoop.util.ToolR"..., 61) = 61
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat org.apache.sqoop.Sqoop.runSq"..., 51) = 51
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat org.apache.sqoop.Sqoop.runTo"..., 50) = 50
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat org.apache.sqoop.Sqoop.runTo"..., 50) = 50
1783 write(2, "\n", 1) = 1
1783 write(2, "\tat org.apache.sqoop.Sqoop.main("..., 47) = 47
1783 write(2, "\n", 1) = 1
1783 lseek(3, 59446352, SEEK_SET) = 59446352
1783 read(3, "PK\3\4\n\0\0\0\0\0`\226\222C\203\312C\246\256\3\0\0\256\3\0\0+\0\0\0", 30) = 30
1783 lseek(3, 59446425, SEEK_SET) = 59446425
1783 read(3, "\312\376\272\276\0\0\0003\0,\1\0\3()I\1\0\5()TK;\1\0&(Ljav"..., 942) = 942
1783 lseek(3, 59443805, SEEK_SET) = 59443805
1783 read(3, "PK\3\4\n\0\0\0\0\0`\226\222C\372\241\273{\236\t\0\0\236\t\0\0007\0\0\0", 30) = 30
1783 lseek(3, 59443890, SEEK_SET) = 59443890
1783 read(3, "\312\376\272\276\0\0\0003\0e\1\0\3()I\1\0\3()V\1\0\3()Z\1\0\5("..., 2462) = 2462
1783 mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fe6d7d03000
1783 clone(child_stack=0x7fe6d7e02ff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7fe6d7e039d0, tls=0x7fe6d7e03700, child_tidptr=0x7fe6d7e039d0) = 1862
1862 set_robust_list(0x7fe6d7e039e0, 24) = 0
1783 futex(0x7fe6f8024b54, FUTEX_WAIT_PRIVATE, 271, NULL <unfinished ...>
1862 gettid() = 1862
1862 rt_sigprocmask(SIG_BLOCK, NULL, [QUIT], 8) = 0
1862 rt_sigprocmask(SIG_UNBLOCK, [HUP INT ILL BUS FPE SEGV USR2 TERM], NULL, 8) = 0
1862 rt_sigprocmask(SIG_BLOCK, [QUIT], NULL, 8) = 0
1862 futex(0x7fe6f8024b54, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f8024b50, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1783 <... futex resumed> ) = 0
1862 futex(0x7fe6fa0bc654, FUTEX_WAIT_PRIVATE, 1, NULL <unfinished ...>
1783 futex(0x7fe6f8024b28, FUTEX_WAKE_PRIVATE, 1) = 0
1783 futex(0x7fe6fa0bc654, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6fa0bc650, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1862 <... futex resumed> ) = 0
1862 futex(0x7fe6fa0bc628, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
1783 mmap(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0 <unfinished ...>
1862 <... futex resumed> ) = 0
1783 <... mmap resumed> ) = 0x7fe6d7c02000
1862 sched_getaffinity(1862, 32, <unfinished ...>
1783 clone( <unfinished ...>
1862 <... sched_getaffinity resumed> {fff, 0, 0, 0}) = 32
1862 sched_getaffinity(1862, 32, {fff, 0, 0, 0}) = 32
1783 <... clone resumed> child_stack=0x7fe6d7d01ff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7fe6d7d029d0, tls=0x7fe6d7d02700, child_tidptr=0x7fe6d7d029d0) = 1863
1863 set_robust_list(0x7fe6d7d029e0, 24 <unfinished ...>
1862 mmap(0x7fe6d7d03000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0 <unfinished ...>
1863 <... set_robust_list resumed> ) = 0
1863 gettid( <unfinished ...>
1862 <... mmap resumed> ) = 0x7fe6d7d03000
1783 futex(0x7fe6f8024b54, FUTEX_WAIT_PRIVATE, 273, NULL <unfinished ...>
1863 <... gettid resumed> ) = 1863
1863 rt_sigprocmask(SIG_BLOCK, NULL, <unfinished ...>
1862 mprotect(0x7fe6d7d03000, 12288, PROT_NONE <unfinished ...>
1863 <... rt_sigprocmask resumed> [QUIT], 8) = 0
1863 rt_sigprocmask(SIG_UNBLOCK, [HUP INT ILL BUS FPE SEGV USR2 TERM], <unfinished ...>
1862 <... mprotect resumed> ) = 0
1863 <... rt_sigprocmask resumed> NULL, 8) = 0
1863 rt_sigprocmask(SIG_BLOCK, [QUIT], NULL, 8) = 0
1863 futex(0x7fe6f8024b54, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f8024b50, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1783 <... futex resumed> ) = 0
1863 futex(0x7fe6fa0bdf54, FUTEX_WAIT_PRIVATE, 1, NULL <unfinished ...>
1862 futex(0x7fe6f8091e54, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f8091e50, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1} <unfinished ...>
1783 futex(0x7fe6f8024b28, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
1862 <... futex resumed> ) = 1
1800 <... futex resumed> ) = 0
1783 <... futex resumed> ) = 0
1800 futex(0x7fe6f8091e28, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
1862 futex(0x7fe6f8091e28, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
1800 <... futex resumed> ) = -1 EAGAIN (Resource temporarily unavailable)
1862 <... futex resumed> ) = 0
1800 futex(0x7fe6f8091e28, FUTEX_WAKE_PRIVATE, 1) = 0
1783 futex(0x7fe6fa0bdf54, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6fa0bdf50, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1} <unfinished ...>
1800 mprotect(0x7fe6ff8e1000, 4096, PROT_READ <unfinished ...>
1783 <... futex resumed> ) = 1
1863 <... futex resumed> ) = 0
1863 futex(0x7fe6fa0bdf28, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
1800 <... mprotect resumed> ) = 0
1783 futex(0x7fe6f8024b54, FUTEX_WAIT_PRIVATE, 275, NULL <unfinished ...>
1862 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_ACCERR, si_addr=0x7fe6ff8e1e80} ---
1863 <... futex resumed> ) = 0
1800 mprotect(0x7fe6ff8e1000, 4096, PROT_READ|PROT_WRITE <unfinished ...>
1862 futex(0x7fe6fa0bc854, FUTEX_WAIT_PRIVATE, 1, NULL <unfinished ...>
1800 <... mprotect resumed> ) = 0
1863 sched_getaffinity(1863, 32, <unfinished ...>
1800 futex(0x7fe6fa0bc854, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6fa0bc850, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1} <unfinished ...>
1863 <... sched_getaffinity resumed> {fff, 0, 0, 0}) = 32
1862 <... futex resumed> ) = 0
1800 <... futex resumed> ) = 1
1863 sched_getaffinity(1863, 32, <unfinished ...>
1800 mprotect(0x7fe6ff8e2000, 4096, PROT_NONE <unfinished ...>
1863 <... sched_getaffinity resumed> {fff, 0, 0, 0}) = 32
1862 futex(0x7fe6fa0bc828, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
1863 mmap(0x7fe6d7c02000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0 <unfinished ...>
1800 <... mprotect resumed> ) = 0
1862 <... futex resumed> ) = 0
1863 <... mmap resumed> ) = 0x7fe6d7c02000
1863 mprotect(0x7fe6d7c02000, 12288, PROT_NONE) = 0
1863 futex(0x7fe6fa0bdf54, FUTEX_WAIT_PRIVATE, 3, NULL <unfinished ...>
1862 rt_sigreturn( <unfinished ...>
1800 sched_yield( <unfinished ...>
1862 <... rt_sigreturn resumed> ) = 140630106709632
1800 <... sched_yield resumed> ) = 0
1862 futex(0x7fe6fa0bc654, FUTEX_WAIT_PRIVATE, 3, NULL <unfinished ...>
1800 sched_yield() = 0
1800 futex(0x7fe6fa0bc654, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6fa0bc650, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1800 futex(0x7fe6f8091e54, FUTEX_WAIT_PRIVATE, 5, NULL <unfinished ...>
1862 <... futex resumed> ) = 0
1862 futex(0x7fe6fa0bc628, FUTEX_WAKE_PRIVATE, 1) = 0
1862 futex(0x7fe6f8024b54, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f8024b50, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1783 <... futex resumed> ) = 0
1862 futex(0x7fe6fa0bc654, FUTEX_WAIT_PRIVATE, 5, NULL <unfinished ...>
1783 futex(0x7fe6f8024b28, FUTEX_WAKE_PRIVATE, 1) = 0
1783 futex(0x7fe6f8091e54, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f8091e50, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1800 <... futex resumed> ) = 0
1783 futex(0x7fe6f8024b54, FUTEX_WAIT_PRIVATE, 277, NULL <unfinished ...>
1800 futex(0x7fe6f8091e28, FUTEX_WAKE_PRIVATE, 1) = 0
1800 futex(0x7fe6f803c954, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f803c950, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1788 <... futex resumed> ) = 0
1800 futex(0x7fe6f803c928, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
1788 futex(0x7fe6f803c928, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
1800 <... futex resumed> ) = 0
1788 <... futex resumed> ) = -1 EAGAIN (Resource temporarily unavailable)
1800 futex(0x7fe6f8091e54, FUTEX_WAIT_PRIVATE, 7, NULL <unfinished ...>
1788 futex(0x7fe6f803c928, FUTEX_WAKE_PRIVATE, 1) = 0
1788 futex(0x7fe6f803aa54, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f803aa50, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1787 <... futex resumed> ) = 0
1787 futex(0x7fe6f803aa28, FUTEX_WAKE_PRIVATE, 1) = 0
1787 futex(0x7fe6f8048154, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f8048150, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1} <unfinished ...>
1797 <... futex resumed> ) = 0
1787 <... futex resumed> ) = 1
1797 futex(0x7fe6f8048128, FUTEX_WAKE_PRIVATE, 1) = 0
1797 futex(0x7fe6f8040654, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f8040650, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1793 <... futex resumed> ) = 0
1793 futex(0x7fe6f8040628, FUTEX_WAKE_PRIVATE, 1) = 0
1793 futex(0x7fe6f8046354, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f8046350, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1} <unfinished ...>
1796 <... futex resumed> ) = 0
1793 <... futex resumed> ) = 1
1796 futex(0x7fe6f8046328, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
1793 futex(0x7fe6f8046328, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
1796 <... futex resumed> ) = -1 EAGAIN (Resource temporarily unavailable)
1793 <... futex resumed> ) = 0
1796 futex(0x7fe6f8046328, FUTEX_WAKE_PRIVATE, 1) = 0
1796 futex(0x7fe6f804bf54, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f804bf50, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1799 <... futex resumed> ) = 0
1799 futex(0x7fe6f804bf28, FUTEX_WAKE_PRIVATE, 1) = 0
1799 futex(0x7fe6f8044454, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f8044450, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1795 <... futex resumed> ) = 0
1795 futex(0x7fe6f8044428, FUTEX_WAKE_PRIVATE, 1) = 0
1795 futex(0x7fe6f8042554, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f8042550, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1794 <... futex resumed> ) = 0
1794 futex(0x7fe6f8042528, FUTEX_WAKE_PRIVATE, 1) = 0
1794 futex(0x7fe6f803e754, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f803e750, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1}) = 1
1792 <... futex resumed> ) = 0
1792 futex(0x7fe6f803e728, FUTEX_WAKE_PRIVATE, 1) = 0
1792 futex(0x7fe6f804a054, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f804a050, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1} <unfinished ...>
1798 <... futex resumed> ) = 0
1792 <... futex resumed> ) = 1
1798 futex(0x7fe6f804a028, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
1792 futex(0x7fe6f804a028, FUTEX_WAKE_PRIVATE, 1 <unfinished ...>
1798 <... futex resumed> ) = -1 EAGAIN (Resource temporarily unavailable)
1792 <... futex resumed> ) = 0
1798 futex(0x7fe6f804a028, FUTEX_WAKE_PRIVATE, 1) = 0
1799 futex(0x7fe6f804bf54, FUTEX_WAIT_PRIVATE, 11, NULL <unfinished ...>
1798 futex(0x7fe6f804a054, FUTEX_WAIT_PRIVATE, 13, NULL <unfinished ...>
1797 futex(0x7fe6f8044454, FUTEX_WAKE_OP_PRIVATE, 1, 1, 0x7fe6f8044450, {FUTEX_OP_SET, 0, FUTEX_OP_CMP_GT, 1} <unfinished ...>
1796 futex(0x7fe6f8046354, FUTEX_WAIT_PRIVATE, 11, NULL <unfinished ...>
1795 futex(0x7fe6f8044454, FUTEX_WAIT_PRIVATE, 11, NULL <unfinished ...>
1794 futex(0x7fe6f8042554, FUTEX_WAIT_PRIVATE, 11, NULL <unfinished ...>
1793 futex(0x7fe6f8040654, FUTEX_WAIT_PRIVATE, 11, NULL <unfinished ...>
1792 futex(0x7fe6f803e754, FUTEX_WAIT_PRIVATE, 11, NULL <unfinished ...>
1788 futex(0x7fe6f803c954, FUTEX_WAIT_PRIVATE, 11, NULL <unfinished ...>
1787 futex(0x7fe6f803aa54, FUTEX_WAIT_PRIVATE, 13, NULL <unfinished ...>
1795 <... futex resumed> ) = -1 EAGAIN (Resource temporarily unavailable)
apologies for the long output.If any other information is required please let me know.
I wrote a short strace cheat sheet that explains how to use strace and about the calls to futex that you may want to look at.
The futex system call is used for implementing synchronization primitives like mutex, semaphores, reader-writer locks, etc. There is nothing wrong with the output you posted above; it indicates that you are likely tracing the main thread of the program which is waiting for a lock to be released.
I would recommend re-running your strace command with -f to trace child processes. Even if your application does not explicitly create additional threads, it is possible that the Java Virtual Machine will create additional threads internally.
Related
Oracle searching a case insensive CLOB
I have some code that searches a CLOB, which works fine. I'm attempting to wrap it in a function that I found online so the search can be CASE insensitive but I am running into some syntax errors and was hoping someone could help me out. Below is my test CASE. I'm using livesql in can anyone wants to emulate my environment. Thanks in advance to all who answer. create or replace type se_obj is object (s number, e number); / create or replace type se_tbl is table of se_obj; / create or replace function search_clob(p_lob clob, p_what varchar2) return se_tbl pipelined as len int := length(p_what); s int; pos int := 1; begin if p_lob is not null then loop s := instr(p_lob, p_what, pos); exit when s = 0; pipe row (se_obj(s, s + len - 1)); pos := s + len; end loop; end if; return; end; / CREATE OR REPLACE FUNCTION upper_clob(p_clob CLOB) RETURN CLOB AS v_clob CLOB; -- TEMPORARY CLOB TO WRITE TO v_posn NUMBER := 1; -- CURRENT POSITION WITHIN CLOB v_holder VARCHAR2(4000); -- CHARACTER STRING HOLDER BEGIN dbms_lob.createtemporary(v_clob,TRUE,dbms_lob.CALL); WHILE (v_posn < dbms_lob.getlength(p_clob)) LOOP v_holder := dbms_lob.substr(p_clob,4000,v_posn); v_posn := v_posn + 4000; v_holder := upper(v_holder); dbms_lob.write(v_clob, length(v_holder),v_posn,v_holder); END LOOP; return v_clob; end; / create table t ( x int primary key, y clob ); -- works fine select t.x id, l.s start_pos, l.e end_pos, dbms_lob.getlength(y) clob_len from t outer apply search_clob(y, 'hello world') l where l.s > 0 -- getting a syntax error select t.x id, l.s start_pos, l.e end_pos, dbms_lob.getlength(y) clob_len from t outer apply search_clob(upper_lob (y), 'HELLO WORLD') l where l.s > 0
It's really overkill to call pl/sql functions for such purposes when you can easily achieve it in SQL... Simple SQL example: https://dbfiddle.uk/?rdbms=oracle_18&fiddle=13fa9071bd6ad34ebbf5fd6de4907a34 Test data: create table t ( x int primary key, y clob ); insert into t select level, to_clob('x') ||rpad(' ',4000,' ')||to_char(level,'0000') ||rpad(' ',4000,' ')||to_char(level,'0000') ||rpad(' ',4000,' ')||to_char(level,'0000') as y from dual connect by level<=30; commit; Simple query: select x, length(y) clob_len, s.* from t outer apply( select nullif(instr(lower(t.y), :subs, 1, level),0) start_pos ,nullif(instr(lower(t.y), :subs, 1, level),0) + length('1') as end_pos from dual connect by instr(lower(t.y), :subs, 1, level)>0 ) s Or using modern SQL Macro: (tested on Oracle 19.11) CREATE OR REPLACE FUNCTION search_clob(input_clob clob, search_string varchar2) return varchar2 SQL_MACRO is BEGIN RETURN q'{ select nullif(instr(lower(search_clob.input_clob), search_clob.search_string, 1, level),0) start_pos ,nullif(instr(lower(search_clob.input_clob), search_clob.search_string, 1, level),0) + length(search_clob.search_string) as end_pos from dual connect by instr(lower(search_clob.input_clob), search_clob.search_string, 1, level)>0 }'; END; / select x, length(y) clob_len, s.* from t outer apply search_clob(t.y, '1') s Example using the first query: SQL> var subs varchar2(10); SQL> exec :subs:='1'; PL/SQL procedure successfully completed. SQL> select 2 x, 3 length(y) clob_len, 4 s.* 5 from t 6 outer apply( 7 select 8 nullif(instr(lower(t.y), :subs, 1, level),0) start_pos 9 ,nullif(instr(lower(t.y), :subs, 1, level),0) + length('1') as end_pos 10 from dual 11 connect by instr(lower(t.y), :subs, 1, level)>0 12 ) s; X CLOB_LEN START_POS END_POS ---------- ---------- ---------- ---------- 1 12016 4006 4007 1 12016 8011 8012 1 12016 12016 12017 2 12016 3 12016 4 12016 5 12016 6 12016 7 12016 8 12016 9 12016 10 12016 4005 4006 10 12016 8010 8011 10 12016 12015 12016 11 12016 4005 4006 11 12016 4006 4007 11 12016 8010 8011 11 12016 8011 8012 11 12016 12015 12016 11 12016 12016 12017 12 12016 4005 4006 12 12016 8010 8011 12 12016 12015 12016 13 12016 4005 4006 13 12016 8010 8011 13 12016 12015 12016 14 12016 4005 4006 14 12016 8010 8011 14 12016 12015 12016 15 12016 4005 4006 15 12016 8010 8011 15 12016 12015 12016 16 12016 4005 4006 16 12016 8010 8011 16 12016 12015 12016 17 12016 4005 4006 17 12016 8010 8011 17 12016 12015 12016 18 12016 4005 4006 18 12016 8010 8011 18 12016 12015 12016 19 12016 4005 4006 19 12016 8010 8011 19 12016 12015 12016 20 12016 21 12016 4006 4007 21 12016 8011 8012 21 12016 12016 12017 22 12016 23 12016 24 12016 25 12016 26 12016 27 12016 28 12016 29 12016 30 12016 57 rows selected.
Algorithm for compressing small files (345 Bytes) [closed]
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers. We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations. Closed 7 years ago. Improve this question I'm looking for a software that can losslessy compress a small amount of noisy data; example: ZmNiYWNma3F5gYqSmqCkpqenpKGdmJONiIN/e3d1c3FxcXFxcnN0dXZ3eXp7fHx9fn5/gIGDhISFhYWFhIOCgYGAgICBgoOEhYeIiYmJiYiGhIF+fHl3dHNyc3N1d3p9gIOGiYuMjY2NjIuKiIeFg4GAfnx7eXl4eHl5enx9fn5/gICAgYGBgYGBgYGBgoKDhISEhISEhIOCgoGAgH9/fn5+fn5/gICAgICAgICAgICAgICAf39/gICBgoOFhoeIiIiIiIeGhYOCgH99fHt6enp6e3x9foCAgoKDg4ODgoKBgH59fHt7e3t8fX5/gIKDhIWFhoaGhoaFhISDgoKBgQ== Original data: 345B (100%), gzip: 280B (81%), bzip2: 289B (84%), lzop: 415B (120%), Are there any other methods I should try?
Since the data is Base64 encoded (every 3 bytes become 4 bytes), the first step would be to decode it (the compressed data will be binary anyway): 344 bytes -> 256 bytes Then, a simple test with standard winzip here shows a compression to 170 bytes (COMP_DEFLATE block). You should get about the same with gzip/zlib. This could probably made somewhat smaller with a higher compression factor. Compressing the original data gives 243 bytes (data block inside the .zip file, the full zip file is 359 bytes, but you don't need all that extra data). So, using zlib on the decoded data, should compress that to ±170 bytes. Looking at the decoded data, an even better compression would be possible. But that depends on the other data having the same structure. Hex dump of the decoded data (a lot of values are repeating, or only changing slightly): 66 63 62 61 63 66 6B 71 79 81 8A 92 9A A0 A4 A6 A7 A7 A4 A1 9D 98 93 8D 88 83 7F 7B 77 75 73 71 71 71 71 71 72 73 74 75 76 77 79 7A 7B 7C 7C 7D 7E 7E 7F 80 81 83 84 84 85 85 85 85 84 83 82 81 81 80 80 80 81 82 83 84 85 87 88 89 89 89 89 88 86 84 81 7E 7C 79 77 74 73 72 73 73 75 77 7A 7D 80 83 86 89 8B 8C 8D 8D 8D 8C 8B 8A 88 87 85 83 81 80 7E 7C 7B 79 79 78 78 79 79 7A 7C 7D 7E 7E 7F 80 80 80 81 81 81 81 81 81 81 81 81 82 82 83 84 84 84 84 84 84 84 83 82 82 81 80 80 7F 7F 7E 7E 7E 7E 7E 7F 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 7F 7F 7F 80 80 81 82 83 85 86 87 88 88 88 88 88 87 86 85 83 82 80 7F 7D 7C 7B 7A 7A 7A 7A 7B 7C 7D 7E 80 80 82 82 83 83 83 83 82 82 81 80 7E 7D 7C 7B 7B 7B 7B 7C 7D 7E 7F 80 82 83 84 85 85 86 86 86 86 86 85 84 84 83 82 82 81 81 Only after a quick look: it should be possible to reach about 2 to 3 bits per byte on average, resulting in 64 to 96 bytes. A closer look at the data: Most values don't change that much. If all data is similar to this, a high compression rate could be achieved using some custom code. For example, the differences could be stored in 1, 2, 3 or 4 bits depending on the block of data (4 bits only needed for the first data points). Another approach, instead of full custom code, would be to compress the differences (delta values) with an existing algorithm (zlib, Huffman coding, and others). Decimal values with 2 rounds of delta-encoding: 102 99 -3 98 -1 2 97 -1 0 99 2 3 102 3 1 107 5 2 113 6 1 121 8 2 129 8 0 138 9 1 146 8 -1 154 8 0 160 6 -2 164 4 -2 166 2 -2 167 1 -1 167 0 -1 164 -3 -3 161 -3 0 157 -4 -1 152 -5 -1 147 -5 0 141 -6 -1 136 -5 1 131 -5 0 127 -4 1 123 -4 0 119 -4 0 117 -2 2 115 -2 0 113 -2 0 113 0 2 113 0 0 113 0 0 113 0 0 114 1 1 115 1 0 116 1 0 117 1 0 118 1 0 119 1 0 121 2 1 122 1 -1 123 1 0 124 1 0 124 0 -1 125 1 1 126 1 0 126 0 -1 127 1 1 128 1 0 129 1 0 131 2 1 132 1 -1 132 0 -1 133 1 1 133 0 -1 133 0 0 133 0 0 132 -1 -1 131 -1 0 130 -1 0 129 -1 0 129 0 1 128 -1 -1 128 0 1 128 0 0 129 1 1 130 1 0 131 1 0 132 1 0 133 1 0 135 2 1 136 1 -1 137 1 0 137 0 -1 137 0 0 137 0 0 136 -1 -1 134 -2 -1 132 -2 0 129 -3 -1 126 -3 0 124 -2 1 121 -3 -1 119 -2 1 116 -3 -1 115 -1 2 114 -1 0 115 1 2 115 0 -1 117 2 2 119 2 0 122 3 1 125 3 0 128 3 0 131 3 0 134 3 0 137 3 0 139 2 -1 140 1 -1 141 1 0 141 0 -1 141 0 0 140 -1 -1 139 -1 0 138 -1 0 136 -2 -1 135 -1 1 133 -2 -1 131 -2 0 129 -2 0 128 -1 1 126 -2 -1 124 -2 0 123 -1 1 121 -2 -1 121 0 2 120 -1 -1 120 0 1 121 1 1 121 0 -1 122 1 1 124 2 1 125 1 -1 126 1 0 126 0 -1 127 1 1 128 1 0 128 0 -1 128 0 0 129 1 1 129 0 -1 129 0 0 129 0 0 129 0 0 129 0 0 129 0 0 129 0 0 129 0 0 130 1 1 130 0 -1 131 1 1 132 1 0 132 0 -1 132 0 0 132 0 0 132 0 0 132 0 0 132 0 0 131 -1 -1 130 -1 0 130 0 1 129 -1 -1 128 -1 0 128 0 1 127 -1 -1 127 0 1 126 -1 -1 126 0 1 126 0 0 126 0 0 126 0 0 127 1 1 128 1 0 128 0 -1 128 0 0 128 0 0 128 0 0 128 0 0 128 0 0 128 0 0 128 0 0 128 0 0 128 0 0 128 0 0 128 0 0 128 0 0 128 0 0 127 -1 -1 127 0 1 127 0 0 128 1 1 128 0 -1 129 1 1 130 1 0 131 1 0 133 2 1 134 1 -1 135 1 0 136 1 0 136 0 -1 136 0 0 136 0 0 136 0 0 135 -1 -1 134 -1 0 133 -1 0 131 -2 -1 130 -1 1 128 -2 -1 127 -1 1 125 -2 -1 124 -1 1 123 -1 0 122 -1 0 122 0 1 122 0 0 122 0 0 123 1 1 124 1 0 125 1 0 126 1 0 128 2 1 128 0 -2 130 2 2 130 0 -2 131 1 1 131 0 -1 131 0 0 131 0 0 130 -1 -1 130 0 1 129 -1 -1 128 -1 0 126 -2 -1 125 -1 1 124 -1 0 123 -1 0 123 0 1 123 0 0 123 0 0 124 1 1 125 1 0 126 1 0 127 1 0 128 1 0 130 2 1 131 1 -1 132 1 0 133 1 0 133 0 -1 134 1 1 134 0 -1 134 0 0 134 0 0 134 0 0 133 -1 -1 132 -1 0 132 0 1 131 -1 -1 130 -1 0 130 0 1 129 -1 -1 129 0 1
Here is a complete set of classes that can be used to compress this data with the following approach: First Base64 decode the string to get bytes (345 -> 256 bytes) Then delta-encode the bytes (meaning, subtract one byte from the previous, storing the results) Another round of delta-encoding (but 3 was worse than 2) Then compress the deltas using Huffman compression This approach got down to 76 bytes including the necessary overhead to decompress later on. A full Mercurial repository with the code can be found here. Note! The code likely contains bugs around edge-cases such as empty or near-empty inputs. A suite of unit-tests can be found in the above linked repository but more testing is likely needed in order to trust this code for production usage. Test program: static void Main(string[] args) { string inputString = "ZmNiYWNma3F5gYqSmqCkpqenpKGdmJONiIN/e3d1c3FxcXFxcnN0dXZ3eXp7fHx9fn5/gIGDhISFhYWFhIOCgYGAgICBgoOEhYeIiYmJiYiGhIF+fHl3dHNyc3N1d3p9gIOGiYuMjY2NjIuKiIeFg4GAfnx7eXl4eHl5enx9fn5/gICAgYGBgYGBgYGBgoKDhISEhISEhIOCgoGAgH9/fn5+fn5/gICAgICAgICAgICAgICAf39/gICBgoOFhoeIiIiIiIeGhYOCgH99fHt6enp6e3x9foCAgoKDg4ODgoKBgH59fHt7e3t8fX5/gIKDhIWFhoaGhoaFhISDgoKBgQ=="; byte[] original = Convert.FromBase64String(inputString); Console.WriteLine($"Original String: {inputString.Length}"); Console.WriteLine($"Original bytes: {original.Length}"); byte[] deltaEncoded = DeltaEncoderDecoder.Encode(original, 2); byte[] compressed = HuffmanCompression.Compress(deltaEncoded); Console.WriteLine($"Compressed bytes: {compressed.Length}"); byte[] deltaDecoded = HuffmanCompression.Decompress(compressed); byte[] decompressed = DeltaEncoderDecoder.Decode(deltaDecoded, 2); Console.WriteLine($"Decompressed bytes: {decompressed.Length}"); Console.WriteLine($"Decompressed == original: {decompressed.Length == original.Length && Enumerable.Range(0, original.Length).All(index => original[index] == decompressed[index])}"); } Output: Original String: 344 Original bytes: 256 Compressed bytes: 76 Decompressed bytes: 256 Decompressed == original: True Here are the necessary classes to both compress and decompress the data: public static class HuffmanCompression { internal const byte CompressedSignature = 255; internal const byte UncompressedSignature = 0; [NotNull] public static byte[] Compress([NotNull] byte[] input) { if (input == null) throw new ArgumentNullException(nameof(input)); if (input.Length == 0) return input; var rootNode = GetNodesFromRawInput(input); var bitStrings = GetBitStringsFromTree(rootNode); var output = new MemoryStream(input.Length); var writer = new BitStreamWriter(output); writer.Write(CompressedSignature); writer.Write(input.Length); WriteNodes(writer, rootNode); WriteStrings(writer, bitStrings, input); writer.Flush(); if (output.Length < input.Length + 1) return output.ToArray(); return EncodeAsUncompressed(input); } [NotNull] private static byte[] EncodeAsUncompressed([NotNull] byte[] input) { var output = new MemoryStream(); output.WriteByte(UncompressedSignature); output.Write(input, 0, input.Length); return output.ToArray(); } private static void WriteStrings([NotNull] BitStreamWriter writer, [NotNull] string[] bitStrings, [NotNull] byte[] input) { foreach (byte value in input) { Assume(bitStrings[value] != null); foreach (char bitChar in bitStrings[value]) writer.Write(bitChar == '1'); } } private static void WriteNodes([NotNull] BitStreamWriter writer, [NotNull] Node node) { if (node.Left == null) { writer.Write(false); writer.Write(node.Value); } else { Assume(node.Right != null); writer.Write(true); WriteNodes(writer, node.Left); WriteNodes(writer, node.Right); } } [NotNull, ItemNotNull] private static string[] GetBitStringsFromTree([NotNull] Node node) { var result = new string[256]; TraverseToGetBitStringsFromTree(node, string.Empty, result); return result; } private static void TraverseToGetBitStringsFromTree([NotNull] Node node, [NotNull] string prefix, [NotNull, ItemNotNull] string[] dictionary) { if (node.Left != null) { Assume(node.Right != null); TraverseToGetBitStringsFromTree(node.Left, prefix + "0", dictionary); TraverseToGetBitStringsFromTree(node.Right, prefix + "1", dictionary); } else dictionary[node.Value] = prefix; } [NotNull] private static Node GetNodesFromRawInput([NotNull] byte[] input) { var occurances = new int[256]; foreach (byte value in input) occurances[value]++; var nodes = new List<Node>(256); for (int index = 0; index < 256; index++) if (occurances[index] > 0) nodes.Add(new Node { Occurances = occurances[index], Value = (byte)index }); while (nodes.Count > 1) { nodes.Sort((n1, n2) => { Assume(n1 != null && n2 != null); return n1.Occurances.CompareTo(n2.Occurances); }); Assume(nodes[0] != null && nodes[1] != null); nodes[0] = new Node { Left = nodes[0], Right = nodes[1], Occurances = nodes[0].Occurances + nodes[1].Occurances }; nodes.RemoveAt(1); } Assume(nodes[0] != null); return nodes[0]; } [NotNull] public static byte[] Decompress([NotNull] byte[] input) { if (input == null) throw new ArgumentNullException(nameof(input)); if (input.Length == 0) return input; if (input[0] != CompressedSignature) return DecodeUncompressed(input); var reader = new BitStreamReader(new MemoryStream(input)); reader.ReadByte(); // skip signature int length = reader.ReadInt32(); var rootNode = ReadNodes(reader); var output = new byte[length]; for (int index = 0; index < length; index++) output[index] = DecompressOneByte(reader, rootNode); return output; } private static byte DecompressOneByte([NotNull] BitStreamReader reader, [NotNull] Node node) { while (node.Left != null) { if (reader.ReadBit()) node = node.Right; else node = node.Left; Assume(node != null); } return node.Value; } [NotNull] private static Node ReadNodes([NotNull] BitStreamReader reader) { if (reader.ReadBit()) return new Node { Left = ReadNodes(reader), Right = ReadNodes(reader) }; return new Node { Value = reader.ReadByte() }; } [NotNull] private static byte[] DecodeUncompressed([NotNull] byte[] input) { return input.Skip(1).ToArray(); } } public class BitStreamReader { [NotNull] private readonly MemoryStream _Source; private byte _Buffer; private int _InBuffer; public BitStreamReader([NotNull] MemoryStream source) { if (source == null) throw new ArgumentNullException(nameof(source)); _Source = source; } public bool ReadBit() { if (_InBuffer == 0) FillBuffer(); return (_Buffer & BitStreamConstants.BitMasks[8 - _InBuffer--]) != 0; } public byte ReadByte() { if (_InBuffer == 8) { _InBuffer = 0; return _Buffer; } return (byte)((ReadBit() ? 128 : 0) | (ReadBit() ? 64 : 0) | (ReadBit() ? 32 : 0) | (ReadBit() ? 16 : 0) | (ReadBit() ? 8 : 0) | (ReadBit() ? 4 : 0) | (ReadBit() ? 2 : 0) | (ReadBit() ? 1 : 0)); } public int ReadInt32() { int result = 0; if (ReadBit()) result |= ReadByte(); if (ReadBit()) result |= ReadByte() << 8; if (ReadBit()) result |= ReadByte() << 16; if (ReadBit()) result |= ReadByte() << 24; return result; } private void FillBuffer() { int value = _Source.ReadByte(); if (value < 0) throw new InvalidOperationException("Read past end of source stream"); _Buffer = (byte)value; _InBuffer = 8; } } public class BitStreamWriter { [NotNull] private readonly MemoryStream _Target; private byte _Buffer; private int _InBuffer; public BitStreamWriter([NotNull] MemoryStream target) { if (target == null) throw new ArgumentNullException(nameof(target)); _Target = target; } public void Flush() { if (_InBuffer == 0) return; _Target.WriteByte(_Buffer); _Buffer = 0; _InBuffer = 0; } public void Write(bool bit) { unchecked { if (bit) _Buffer = (byte)(_Buffer | 1 << (7 - _InBuffer)); if (++_InBuffer == 8) Flush(); } } public void Write(byte value) { for (int index = 0; index < 8; index++) Write((value & BitStreamConstants.BitMasks[index]) != 0); } public void Write(int value) { byte b0 = (byte)(value & 0xff); byte b1 = (byte)((value >> 8) & 0xff); byte b2 = (byte)((value >> 16) & 0xff); byte b3 = (byte)((value >> 24) & 0xff); Write(b0 != 0); if (b0 != 0) Write(b0); Write(b1 != 0); if (b1 != 0) Write(b1); Write(b2 != 0); if (b2 != 0) Write(b2); Write(b3 != 0); if (b3 != 0) Write(b3); } } internal static class BitStreamConstants { [NotNull] public static readonly byte[] BitMasks = { 128, 64, 32, 16, 8, 4, 2, 1 }; public const byte CompressedSignature = 255; } public static class DeltaEncoderDecoder { [NotNull] public static byte[] Encode([NotNull] byte[] input, int iterations) { if (input == null) throw new ArgumentNullException(nameof(input)); var output = new byte[input.Length]; Buffer.BlockCopy(input, 0, output, 0, input.Length); while (iterations-- > 0) { byte previous = 0; for (int index = 0; index < output.Length; index++) { byte current = output[index]; output[index] = (byte)(current - previous); previous = current; } } return output; } [NotNull] public static byte[] Decode([NotNull] byte[] input, int iterations) { if (input == null) throw new ArgumentNullException(nameof(input)); var output = new byte[input.Length]; Buffer.BlockCopy(input, 0, output, 0, input.Length); while (iterations-- > 0) { byte previous = 0; for (int index = 0; index < output.Length; index++) { output[index] = (byte)(previous + output[index]); previous = output[index]; } } return output; } }
Gammu cannot contact device after sending first sms
I have installed gammu 1.33.0-3 and gammu-smsd 1.33.0-3. When starting gammu and injecting some message into the SQL-Queue, the message is being sent. However, after the first sms nothing works anymore and I need to kill -9 gammu in order to be able to start it again. Please see the information below. Would be great if someone is able to help. root#sms ~ $ gammu identify Device : /dev/ttyUSB0 Manufacturer : Huawei Model : unknown (K3765) Firmware : 11.126.03.06.00 IMEI : 358... SIM IMSI : 262... When sending the first sms, everything works fine, but gammu-smsd seems to break directly afterwards. strace shows the following odd behavior of gammu-smsd after sending the first sms. It seems like gammu-smsd is stuck doing something with /etc/localtime. The screen gets pretty much spammed with those entries. nanosleep({1, 0}, 0x7fffbacc4fa0) = 0 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 nanosleep({1, 0}, 0x7fffbacc4fa0) = 0 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 nanosleep({1, 0}, 0x7fffbacc4fa0) = 0 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 nanosleep({1, 0}, 0x7fffbacc4fa0) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 [...] repeats for hundreds of times.. write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 357) = 357 poll([{fd=4, events=POLLIN|POLLPRI}], 1, 0) = 0 (Timeout) write(4, "-\1\0\0\3SELECT `ID`, `InsertIntoDB`"..., 305) = 305 read(4, "\1\0\0\1\4+\0\0\2\3def\5gammu\6outbox\6outbo"..., 16384) = 325 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 202) = 202 poll([{fd=4, events=POLLIN|POLLPRI}], 1, 0) = 0 (Timeout) write(4, "\222\0\0\0\3UPDATE outbox SET `SendingT"..., 150) = 150 read(4, "0\0\0\1\0\1\0\2\0\0\0(Rows matched: 1 Cha"..., 16384) = 52 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 [...] repeats for hundreds of times.. write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 229) = 229 poll([{fd=4, events=POLLIN|POLLPRI}], 1, 0) = 0 (Timeout) write(4, "\255\0\0\0\3SELECT `Text`, `Coding`, `U"..., 177) = 177 read(4, "\1\0\0\1\v/\0\0\2\3def\5gammu\6outbox\6outbo"..., 16384) = 936 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 66) = 66 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 71) = 71 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 63) = 63 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 87) = 87 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 131) = 131 write(5, "AT+CSCA?\r", 9) = 9 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 select(6, [5], NULL, NULL, {0, 50000}) = 1 (in [5], left {0, 46166}) read(5, "AT+CSCA?\r", 65536) = 9 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 select(6, [5], NULL, NULL, {0, 50000}) = 1 (in [5], left {0, 49778}) read(5, "\r\n+CSCA: \"+491770610000\",145\r\n\r\n"..., 65536) = 36 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 63) = 63 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 81) = 81 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 57) = 57 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 68) = 68 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 68) = 68 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 89) = 89 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 131) = 131 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 131) = 131 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 131) = 131 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 69) = 69 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 104) = 104 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 111) = 111 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 86) = 86 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 90) = 90 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 65) = 65 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 70) = 70 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 80) = 80 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 73) = 73 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 87) = 87 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 131) = 131 write(5, "AT+CBC\r", 7) = 7 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 select(6, [5], NULL, NULL, {0, 50000}) = 1 (in [5], left {0, 49418}) read(5, "AT+CBC\r", 65536) = 7 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 select(6, [5], NULL, NULL, {0, 50000}) = 1 (in [5], left {0, 49905}) read(5, "\r\n+CBC: 2,0\r\n\r\nOK\r\n", 65536) = 19 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 61) = 61 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 64) = 64 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 57) = 57 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 68) = 68 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 68) = 68 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 89) = 89 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 131) = 131 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 131) = 131 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 73) = 73 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 86) = 86 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 63) = 63 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 63) = 63 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 79) = 79 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 80) = 80 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 78) = 78 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 87) = 87 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 write(3, "Wed 2015/07/08 00:05:51 gammu-sm"..., 131) = 131 write(5, "AT+CSQ\r", 7) = 7 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 select(6, [5], NULL, NULL, {0, 50000}) = 1 (in [5], left {0, 46575}) read(5, "AT+CSQ\r", 65536) = 7 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0 select(6, [5], NULL, NULL, {0, 50000}) = 1 (in [5], left {0, 49808}) read(5, "\r\n+CSQ: 11,99\r\n\r\nOK\r\n", 65536) = 21 Config Files /root/.gammurc [gammu] port = /dev/ttyUSB0 model = connection = at synchronizetime = yes logfile = /var/log/sms/gammu.log logformat = nothing use_locking = no gammuloc = /etc/gammu-smsdrc # This is a sample Gammu SMSD configuration file. It's required for gammu-smsd, # see gammu-smsdrc(5) for documentation. # Gammu configuration, this section is like section "gammu" in "gammurc" file, # see gammurc(5) for documentation. [gammu] device = /dev/ttyUSB0 connection = at [smsd] Service = sql Driver = native_mysql User = xxx Password = xxx PC = localhost Database = xxx PIN = LogFile = /var/log/sms/gammu-smsd debuglevel = 255 PhoneID = UMTSStick receive = 0
It would be good to see SMSD log as well, but I think it's bug which has been fixed in 1.35.0, so please upgrade Gammu.
Oracle Analytics Function Usage
I am new to Oracle Analytics . Can any one help me to resolve the following. SELECT year, month, week, C.cpg_pk CPG, C.dep_pk DEPT, T.cust_id CUST_ID, D1.r_id R_ID, Decode(d2.at_code, '3', func1.Get_att(d2.at_code, D2.val_code)) AS P1, Decode(d2.at_code, '2', func1.Get_att(d2.at_code, D2.val_code)) AS IC, Decode(d2.at_code, '1', func1.Get_att(d2.at_code, D2.val_code)) AS B1, Decode(func1.Get_att(d2.at_code, D2.val_code), 2, d2.at_code) AS P2, Decode(func1.Get_att(d2.at_code, D2.val_code), 5, d2.at_code) AS B2, Count(DISTINCT A.cust_id) TOTAL_ACC , Count(DISTINCT T.txn_pk) TOTAL_TXN, SUM(am_amount) TOTAL_AMT FROM t_header T, cust_master A, tx_details1 D1, tx_details2 D2, cpg_master C WHERE A.TYPE = 0 AND T.cust_id = A.cust_id AND T.txn_pk = 5001 AND T.txn_pk = D1.txn_pk AND T.txn_pk = D2.txn_pk AND D1.cpg_pk = C.cpg_pk AND D1.op = 1 GROUP BY year, month, week, C.cpg_pk, C.dep_pk, t.cust_id, D1.r_id, Decode(d2.at_code, '3', func1.Get_att(d2.at_code, D2.val_code)), Decode(d2.at_code, '2', func1.Get_att(d2.at_code, D2.val_code)), Decode(d2.at_code, '1', func1.Get_att(d2.at_code, D2.val_code)), Decode(func1.Get_att(d2.at_code, D2.val_code), 2, d2.at_code), Decode(func1.Get_att(d2.at_code, D2.val_code), 5, d2.at_code) Its generated output is as follows: YEAR MONTH WEEK CPG DEPT CUST_ID R_ID P1 IC B1 P2 B2 TOTAL 2012 08 32 127 -1 10019 3665 134 23100.09 2012 08 32 127 -1 10019 3665 135 23100.09 2012 08 32 127 -1 10019 3665 723 23100.09 2012 08 32 127 -1 10019 3665 714 23100.09 2012 08 32 127 -1 10019 3665 41 23100.09 2012 08 32 127 -1 10019 3665 42 23100.09 2012 08 32 127 -1 10019 3665 21 23100.09 2012 08 32 128 -1 10019 3665 134 23100.09 2012 08 32 128 -1 10019 3665 135 23100.09 2012 08 32 128 -1 10019 3665 723 23100.09 2012 08 32 128 -1 10019 3665 714 23100.09 2012 08 32 128 -1 10019 3665 41 23100.09 2012 08 32 128 -1 10019 3665 42 23100.09 2012 08 32 128 -1 10019 3665 21 23100.09 Here the values are repeating. I tried to eliminate the repeating with a group by, but didn't succeed. Could you help me? The required output is this: YEAR MONTH WEEK CPG DEPT CUST_ID R_ID P1 IC B1 P2 B2 TOTAL_AMT --------------------------------------------------------------------------------- 2012 08 32 127 -1 10019 3665 21 714 723 41 134 23100.09 2012 08 32 127 -1 10019 3665 21 714 723 41 135 23100.09 2012 08 32 127 -1 10019 3665 21 714 723 42 134 23100.09 2012 08 32 127 -1 10019 3665 21 714 723 42 135 23100.09 2012 08 32 128 -1 10019 3665 21 714 723 41 134 23100.09 2012 08 32 128 -1 10019 3665 21 714 723 41 135 23100.09 2012 08 32 128 -1 10019 3665 21 714 723 42 134 23100.09 2012 08 32 128 -1 10019 3665 21 714 723 42 135 23100.09 The main thing is year, month, week, cpg, dept, cust_id, r_id, p1, ic, b1, p2, b2 it should be unique row. Is it achievable using analytical functions or do I need to write PL/SQL? is my question is sensable ?
with t1 as( select 2012 YEAR1, 08 MONTH1, 32 WEEK, 127 CPG, -1 DEPT, 10019 CUST_ID, 3665 R_ID, null P1, null IC, 723 B1,null P2, null B2, 23100.09 TOTAL from dual union all -- select 2012, 08, 32, 127, -1, 10019, 3665, null, null, null, null, 135 , 23100.09 from dual union all -- select 2012, 08, 32, 127, -1, 10019, 3665, null, null, null , null, 134, 23100.09 from dual union all select 2012, 08, 32, 127, -1, 10019, 3665, null, 714 , null, null, null, 23100.09 from dual union all -- select 2012, 08, 32, 127, -1, 10019, 3665, null, null ,null, 41, null, 23100.09 from dual union all -- select 2012, 08, 32, 127, -1, 10019, 3665, null, null, null, 42, null, 23100.09 from dual union all -- select 2012, 08, 32, 127, -1, 10019, 3665, 21 , null, null, null, null, 23100.09 from dual union all -- select 2012, 08, 32, 128, -1, 10019, 3665, null, null, null, null, 134 , 23100.09 from dual union all -- select 2012, 08, 32, 128, -1, 10019, 3665, null, null, null, null, 135 , 23100.09 from dual union all select 2012, 08, 32, 128, -1, 10019, 3665, null, null, 723 , null, null, 23100.09 from dual union all select 2012, 08, 32, 128, -1, 10019, 3665, null, 714 , null, null, null, 23100.09 from dual union all -- select 2012, 08, 32, 128, -1, 10019, 3665, null, null ,null, 41, null, 23100.09 from dual union all -- select 2012, 08, 32, 128, -1, 10019, 3665, null, null, null, 42, null, 23100.09 from dual union all -- select 2012, 08, 32, 128, -1, 10019, 3665, 21 , null, null, null, null, 23100.09 from dual ) select t1p1.YEAR1, t1p1.month1, t1p1.week, t1p1.cpg, t1p1.dept, t1p1.cust_id, t1p1.r_id, t1p1.p1,t1ic.ic, t1b1.b1, t1p2.p2, t1b2.b2, t1p1.total from (select YEAR1, month1, week, cpg, dept, cust_id, r_id, p1 , total from t1 where p1 is not null) t1p1, (select YEAR1, month1, week, cpg, dept, cust_id, r_id, ic from t1 where ic is not null) t1ic, (select YEAR1, month1, week, cpg, dept, cust_id, r_id, b1 from t1 where b1 is not null) t1b1, (select YEAR1, month1, week, cpg, dept, cust_id, r_id, p2 from t1 where p2 is not null) t1p2, (select YEAR1, month1, week, cpg, dept, cust_id, r_id, b2 from t1 where b2 is not null) t1b2 where t1p1.year1 = t1ic.year1(+) and t1p1.year1 = t1b1.year1(+) and t1p1.year1 = t1p2.year1(+) and t1p1.year1 = t1b2.year1(+) and t1p1.month1 = t1ic.month1(+) and t1p1.month1 = t1b1.month1(+) and t1p1.month1 = t1p2.month1(+) and t1p1.month1 = t1b2.month1(+) and t1p1.week = t1ic.week(+) and t1p1.week = t1b1.week(+) and t1p1.week = t1p2.week(+) and t1p1.week = t1b2.week(+) and t1p1.cpg = t1ic.cpg(+) and t1p1.cpg = t1b1.cpg(+) and t1p1.cpg = t1p2.cpg(+) and t1p1.cpg = t1b2.cpg(+) and t1p1.dept = t1ic.dept(+) and t1p1.dept = t1b1.dept(+) and t1p1.dept = t1p2.dept(+) and t1p1.dept = t1b2.dept(+) and t1p1.cust_id = t1ic.cust_id(+) and t1p1.cust_id = t1b1.cust_id(+) and t1p1.cust_id = t1p2.cust_id (+)and t1p1.cust_id = t1b2.cust_id(+) and t1p1.r_id = t1ic.r_id(+) and t1p1.r_id = t1b1.r_id(+) and t1p1.r_id = t1p2.r_id (+) and t1p1.r_id = t1b2.r_id(+) order by t1p1.YEAR1, t1p1.month1, t1p1.week, t1p1.cpg, t1p1.dept, t1p1.cust_id, t1p1.r_id, t1p1.p1,t1ic.ic, t1b1.b1, t1p2.p2, t1b2.b2 /
What are the mathematical/computational principles behind this game?
My kids have this fun game called Spot It! The game constraints (as best I can describe) are: It is a deck of 55 cards On each card are 8 unique pictures (i.e. a card can't have 2 of the same picture) Given any 2 cards chosen from the deck, there is 1 and only 1 matching picture. Matching pictures may be scaled differently on different cards but that is only to make the game harder (i.e. a small tree still matches a larger tree) The principle of the game is: flip over 2 cards and whoever first picks the matching picture gets a point. Here's a picture for clarification: (Example: you can see from the bottom 2 cards above that the matching picture is the green dinosaur. Between the bottom-right and middle-right picture, it's a clown's head.) I'm trying to understand the following: What are the minimum number of different pictures required to meet these criteria and how would you determine this? Using pseudocode (or Ruby), how would you generate 55 game cards from an array of N pictures (where N is the minimum number from question 1)? Update: Pictures do occur more than twice per deck (contrary to what some have surmised). See this picture of 3 cards, each with a lightning bolt:
Finite Projective Geometries The axioms of projective (plane) geometry are slightly different than the Euclidean geometry: Every two points have exactly one line that passes through them (this is the same). Every two lines meet in exactly one point (this is a bit different from Euclid). Now, add "finite" into the soup and you have the question: Can we have a geometry with just 2 points? With 3 points? With 4? With 7? There are still open questions regarding this problem but we do know this: If there are geometries with Q points, then Q = n^2 + n + 1 and n is called the order of the geometry. There are n+1 points in every line. From every point, pass exactly n+1 lines. Total number of lines is also Q. And finally, if n is prime, then there does exists a geometry of order n. What does that have to do with the puzzle, one may ask. Put card instead of point and picture instead of line and the axioms become: Every two cards have exactly one picture in common. For every two pictures there is exactly one card that has both of them. Now, lets take n=7 and we have the order-7 finite geometry with Q = 7^2 + 7 + 1 . That makes Q=57 lines (pictures) and Q=57 points (cards). I guess the puzzle makers decided that 55 is more round number than 57 and left 2 cards out. We also get n+1 = 8, so from every point (card), 8 lines pass (8 pictures appear) and every line (picture) has 8 points (appears in 8 cards). Here's a representation of the most famous finite projective (order-2) plane (geometry) with 7 points, known as Fano Plane, copied from Noelle Evans - Finite Geometry Problem Page I was thinking of creating an image that explain how the above order-2 plane could be made a similar puzzle with 7 cards and 7 pictures, but then a link from the math.exchange twin question has exactly such a diagram: Dobble-et-la-geometrie-finie
For those who have trouble picturing the projective plane geometry with 57 points, there is a really nice, intuitive way to construct the game with 57 cards and 57 symbols (based on the answer by Yuval Filmus for this question): For cards with 8 symbols, create a 7x7 grid of unique symbols. Add an additional 8 symbols for the "slopes" from 0 to 6, plus one for infinity slope. Each card is a line on the grid (7 symbols) plus one symbol from the slope set for the slope of the line. Lines have an offset (i.e. starting point on the left), and a slope (i.e. how many symbols to go up for each step right). When the line leaves the grid at the top, re-enter at the bottom. See this example figure (pictures from boardgamegeek) for two such cards: In the example, I take one line with slope zero (red), and one with slope 1 (green). They intersect at exactly one common point (the owl). This method ensures that any two cards have exactly one common symbol, because If the slopes are different, then the lines will always intersect at exactly one point. If the slopes are the same, then the lines will not intersect and there will be no common symbol from the grid. In this case, the slope symbol will be the same. In this way, we can construct 7x7 cards (7 offsets and 7 slopes). We can also construct seven additional cards from vertical lines through the grid (i.e. taking each column). For those, the infinity slope icon is used. Because each card consists of seven symbols from the grid and exactly one "slope" symbol, we can create one additional card, which simply consists of all the 8 slope symbols. This leaves us with 7x8 + 1 = 57 possible cards, and 7 x 7 + 8 = 57 required symbols. (Naturally, this only works with a prime-number-sized grid (e.g. n=7). Otherwise, lines of different slope could have zero or more than one intersection if the slope is a divisor of the grid size.)
So there are k=55 cards containing m=8 pictures each from a pool of n pictures total. We can restate the question 'How many pictures n do we need, so that we can construct a set of k cards with only one shared picture between any pair of cards?' equivalently by asking: Given an n-dimensional vector space and the set of all vectors, which contain exactly m elements equal to one and all other zero, how big has n to be, so that we can find a set of k vectors, whose pairwise dot products are all equal to 1? There are exactly (n choose m) possible vectors to build pairs from. So we at least need a big enough n so that (n choose m) >= k. This is just a lower bound, so for fulfilling the pairwise compatibility constraint we possibly need a much higher n. Just for experimenting a bit i wrote a small Haskell program to calculate valid card sets: Edit: I just realized after seeing Neil's and Gajet's solution, that the algorithm i use doesn't always find the best possible solution, so everything below isn't necessarily valid. I'll try to update my code soon. module Main where cardCandidates n m = cardCandidates' [] (n-m) m cardCandidates' buildup 0 0 = [buildup] cardCandidates' buildup zc oc | zc>0 && oc>0 = zerorec ++ onerec | zc>0 = zerorec | otherwise = onerec where zerorec = cardCandidates' (0:buildup) (zc-1) oc onerec = cardCandidates' (1:buildup) zc (oc-1) dot x y = sum $ zipWith (*) x y compatible x y = dot x y == 1 compatibleCards = compatibleCards' [] compatibleCards' valid [] = valid compatibleCards' valid (c:cs) | all (compatible c) valid = compatibleCards' (c:valid) cs | otherwise = compatibleCards' valid cs legalCardSet n m = compatibleCards $ cardCandidates n m main = mapM_ print [(n, length $ legalCardSet n m) | n<-[m..]] where m = 8 The resulting maximum number of compatible cards for m=8 pictures per card for different number of pictures to choose from n for the first few n looks like this: This brute force method doesn't get very far though because of combinatorial explosion. But i thought it might still be interesting. Interestingly, it seems that for given m, k increases with n only up to a certain n, after which it stays constant. This means, that for every number of pictures per card there is a certain number of pictures to choose from, that results in maximum possible number of legal cards. Adding more pictures to choose from past that optimal number doesn't increase the number of legal cards any further. The first few optimal k's are:
Others have described the general framework for the design (finite projective plane) and shown how to generate finite projective planes of prime order. I would just like to fill in some gaps. Finite projective planes can be generated for many different orders, but they are most straightforward in the case of prime order p. Then the integers modulo p form a finite field which can be used to describe coordinates for the points and lines in the plane. There are 3 different kinds of coordinates for points: (1,x,y), (0,1,x), and (0,0,1), where x and y can take on values from 0 to p-1. The 3 different kinds of points explains the formula p^2+p+1 for the number of points in the system. We can also describe lines with the same 3 different kinds of coordinates: [1,x,y], [0,1,x], and [0,0,1]. We compute whether a point and line are incident by whether the dot product of their coordinates is equal to 0 mod p. So for example the point (1,2,5) and the line [0,1,1] are incident when p=7 since 1*0+2*1+5*1 = 7 == 0 mod 7, but the point (1,3,3) and the line [1,2,6] are not incident since 1*1+3*2+3*6 = 25 != 0 mod 7. Translating into the language of cards and pictures, that means the picture with coordinates (1,2,5) is contained in the card with coordinates [0,1,1], but the picture with coordinates (1,3,3) is not contained in the card with coordinates [1,2,6]. We can use this procedure to develop a complete list of cards and the pictures that they contain. I think it's easier to think of pictures as points and cards as lines, but there's a duality in projective geometry between points and lines so it really doesn't matter. However, in what follows I will be using points for pictures and lines for cards. The same construction works for any finite field. We know that there is a finite field of order q if and only if q=p^k, a prime power. The field is called GF(p^k) which stands for "Galois field". The fields are not as easy to construct in the prime power case as they are in the prime case. Fortunately, the hard work has already been done and implemented in free software, namely Sage Math. To get a projective plane design of order 4, for example, just type PG = designs.ProjectiveGeometryDesign(2,1,GF(4),point_coordinates=0) PG.blocks() and you'll obtain output that looks like [[0,1,2,3,20], [0,4,8,12,16], [0,5,10,15,19], [0,6,11,13,17], [0,7,9,14,18], [1,4,11,14,19], [1,5,9,13,16], [1,6,8,15,18], [1,7,10,12,17], [2,4,9,15,17], [2,5,11,12,18], [2,6,10,14,16], [2,7,8,13,19], [3,4,10,13,18], [3,5,8,14,17], [3,6,9,12,19], [3,7,11,15,16], [4,5,6,7,20], [8,9,10,11,20], [12,13,14,15,20], [16,17,18,19,20]] I interpret the above as follows: there are 21 pictures labelled from 0 to 20. Each of the blocks (lines in projective geometry) tells me which pictures appears on a card. For example, the first card will have pictures 0, 1, 2, 3, and 20; the second card will have pictures 0, 4, 8, 12, and 16; and so on. The system of order 7 can be generated by PG = designs.ProjectiveGeometryDesign(2,1,GF(7),point_coordinates=0) PG.blocks() which generates the output [[0, 1, 2, 3, 4, 5, 6, 56], [0, 7, 14, 21, 28, 35, 42, 49], [0, 8, 16, 24, 32, 40, 48, 50], [0, 9, 18, 27, 29, 38, 47, 51], [0, 10, 20, 23, 33, 36, 46, 52], [0, 11, 15, 26, 30, 41, 45, 53], [0, 12, 17, 22, 34, 39, 44, 54], [0, 13, 19, 25, 31, 37, 43, 55], [1, 7, 20, 26, 32, 38, 44, 55], [1, 8, 15, 22, 29, 36, 43, 49], [1, 9, 17, 25, 33, 41, 42, 50], [1, 10, 19, 21, 30, 39, 48, 51], [1, 11, 14, 24, 34, 37, 47, 52], [1, 12, 16, 27, 31, 35, 46, 53], [1, 13, 18, 23, 28, 40, 45, 54], [2, 7, 19, 24, 29, 41, 46, 54], [2, 8, 14, 27, 33, 39, 45, 55], [2, 9, 16, 23, 30, 37, 44, 49], [2, 10, 18, 26, 34, 35, 43, 50], [2, 11, 20, 22, 31, 40, 42, 51], [2, 12, 15, 25, 28, 38, 48, 52], [2, 13, 17, 21, 32, 36, 47, 53], [3, 7, 18, 22, 33, 37, 48, 53], [3, 8, 20, 25, 30, 35, 47, 54], [3, 9, 15, 21, 34, 40, 46, 55], [3, 10, 17, 24, 31, 38, 45, 49], [3, 11, 19, 27, 28, 36, 44, 50], [3, 12, 14, 23, 32, 41, 43, 51], [3, 13, 16, 26, 29, 39, 42, 52], [4, 7, 17, 27, 30, 40, 43, 52], [4, 8, 19, 23, 34, 38, 42, 53], [4, 9, 14, 26, 31, 36, 48, 54], [4, 10, 16, 22, 28, 41, 47, 55], [4, 11, 18, 25, 32, 39, 46, 49], [4, 12, 20, 21, 29, 37, 45, 50], [4, 13, 15, 24, 33, 35, 44, 51], [5, 7, 16, 25, 34, 36, 45, 51], [5, 8, 18, 21, 31, 41, 44, 52], [5, 9, 20, 24, 28, 39, 43, 53], [5, 10, 15, 27, 32, 37, 42, 54], [5, 11, 17, 23, 29, 35, 48, 55], [5, 12, 19, 26, 33, 40, 47, 49], [5, 13, 14, 22, 30, 38, 46, 50], [6, 7, 15, 23, 31, 39, 47, 50], [6, 8, 17, 26, 28, 37, 46, 51], [6, 9, 19, 22, 32, 35, 45, 52], [6, 10, 14, 25, 29, 40, 44, 53], [6, 11, 16, 21, 33, 38, 43, 54], [6, 12, 18, 24, 30, 36, 42, 55], [6, 13, 20, 27, 34, 41, 48, 49], [7, 8, 9, 10, 11, 12, 13, 56], [14, 15, 16, 17, 18, 19, 20, 56], [21, 22, 23, 24, 25, 26, 27, 56], [28, 29, 30, 31, 32, 33, 34, 56], [35, 36, 37, 38, 39, 40, 41, 56], [42, 43, 44, 45, 46, 47, 48, 56], [49, 50, 51, 52, 53, 54, 55, 56]] If you want up to 57 cards you can use GF(7). If you want 58 cards you'll have to use a larger field. Since 8 is a power of a prime, you could use GF(8). Note that the projective plane based on GF(8) will have 8^2 + 8 + 1 = 73 points and 73 lines. You can make 73 cards, but then just throw away 15 of them if you want a set of exactly 58 cards. If you want between 73 and 91 cards you could use GF(9), etc. There is no GF(10) because 10 is not a power of a prime. GF(11) is next, then GF(13), then GF(16) because 16=2^4, and so on. By the way, I have a theory that the original Spot It deck uses 55, not 57, because they contracted a playing card manufacturer which was already tooled for decks of 55 cards (52 regular cards in a deck, plus two jokers and a title card).
I just found a way to do it with 57 or 58 pictures but now I have a very bad headache, I'll post the ruby code in 8-10 hours after I slept well! just a hint my my solution every 7 cards share same mark and total 56 cards can be constructed using my solution. here is the code that generates all 57 cards that ypercube was talking about. it uses exactly 57 pictures, and sorry guy's I've written actual C++ code but knowing that vector <something> is an array containing values of type something it's easy to understand what this code does. and this code generates P^2+P+1 cards using P^2+P+1 pictures each containing P+1 picture and sharing only 1 picture in common, for every prime P value. which means we can have 7 cards using 7 pictures each having 3 pictures(for p=2), 13 cards using 13 pictures(for p=3), 31 cards using 31 pictures(for p=5), 57 cards for 57 pictures(for p=7) and so on... #include <iostream> #include <vector> using namespace std; vector <vector<int> > cards; void createcards(int p) { cards.resize(0); for (int i=0;i<p;i++) { cards.resize(cards.size()+1); for(int j=0;j<p;j++) { cards.back().push_back(i*p+j); } cards.back().push_back(p*p+1); } for (int i=0;i<p;i++) { for(int j=0;j<p;j++) { cards.resize(cards.size()+1); for(int k=0;k<p;k++) { cards.back().push_back(k*p+(j+i*k)%p); } cards.back().push_back(p*p+2+i); } } cards.resize(cards.size()+1); for (int i=0;i<p+1;i++) cards.back().push_back(p*p+1+i); } void checkCards() { cout << "---------------------\n"; for(unsigned i=0;i<cards.size();i++) { for(unsigned j=0;j<cards[i].size();j++) { printf("%3d",cards[i][j]); } cout << "\n"; } cout << "---------------------\n"; for(unsigned i=0;i<cards.size();i++) { for(unsigned j=i+1;j<cards.size();j++) { int sim = 0; for(unsigned k=0;k<cards[i].size();k++) for(unsigned l=0;l<cards[j].size();l++) if (cards[i][k] == cards[j][l]) sim ++; if (sim != 1) cout << "there is a problem between cards : " << i << " " << j << "\n"; } } } int main() { int p; for(cin >> p; p!=0;cin>> p) { createcards(p); checkCards(); } } again sorry for the delayed code.
Here's Gajet's solution in Python, since I find Python more readable. I have modified it so that it works with non-prime numbers as well. I have used Thies insight to generate some more easily understood display code. from __future__ import print_function from itertools import * def create_cards(p): for min_factor in range(2, 1 + int(p ** 0.5)): if p % min_factor == 0: break else: min_factor = p cards = [] for i in range(p): cards.append(set([i * p + j for j in range(p)] + [p * p])) for i in range(min_factor): for j in range(p): cards.append(set([k * p + (j + i * k) % p for k in range(p)] + [p * p + 1 + i])) cards.append(set([p * p + i for i in range(min_factor + 1)])) return cards, p * p + p + 1 def display_using_stars(cards, num_pictures): for pictures_for_card in cards: print("".join('*' if picture in pictures_for_card else ' ' for picture in range(num_pictures))) def check_cards(cards): for card, other_card in combinations(cards, 2): if len(card & other_card) != 1: print("Cards", sorted(card), "and", sorted(other_card), "have intersection", sorted(card & other_card)) cards, num_pictures = create_cards(7) display_using_stars(cards, num_pictures) check_cards(cards) With output: *** * *** * **** * * * * * * * * * * * * * * * * * ** * ** * * * * * * * * * * * * * * ****
Using the z3 theorem prover Let P be the number of symbols per card. According to this article and ypercubeᵀᴹ's answer there are N = P**2 - P + 1 cards and symbols, respectively. A deck of cards can be represented with its incidence matrix which has a row for each card and a column for each possible symbol. Its (i,j) element is 1 if card i has symbol j on it. We only need to fill this matrix with these constraints in mind: every element is either zero or one the sum of each row is exactly P the sum of each column is exactly P any two rows must have exactly one symbol in common That means N**2 variables and N**2 + 2*N + (N choose 2) constraints. It seems to be manageable in a not-so-long time with z3 for small inputs. edit: Unfortunately P=8 seems to be too big for this method. I killed the process after 14 hour of computation time. from z3 import * from itertools import combinations def is_prime_exponent(K): return K > 1 and K not in 6 # next non-prime exponent is 10, # but that is too big anyway def transposed(rows): return zip(*rows) def spotit_z3(symbols_per_card): K = symbols_per_card - 1 N = symbols_per_card ** 2 - symbols_per_card + 1 if not is_prime_exponent(K): raise TypeError("Symbols per card must be a prime exponent plus one.") constraints = [] # the rows of the incidence matrix s = N.bit_length() rows = [[BitVec("r%dc%d" % (r, c), s) for c in range(N)] for r in range(N)] # every element must be either 1 or 0 constraints += [Or([elem == 1, elem == 0]) for row in rows for elem in row] # sum of rows and cols must be exactly symbols_per_card constraints += [Sum(row) == symbols_per_card for row in rows] constraints += [Sum(col) == symbols_per_card for col in transposed(rows)] # Any two rows must have exactly one symbol in common, in other words they # differ in (symbols_per_card - 1) symbols, so their element-wise XOR will # have 2 * (symbols_per_card - 1) ones. D = 2 * (symbols_per_card - 1) for row_a, row_b in combinations(rows, 2): constraints += [Sum([a ^ b for a, b in zip(row_a, row_b)]) == D] solver = Solver() solver.add(constraints) if solver.check() == unsat: raise RuntimeError("Could not solve it :(") # create the incidence matrix model = solver.model() return [[model[elem].as_long() for elem in row] for row in rows] if __name__ == "__main__": import sys symbols_per_card = int(sys.argv[1]) incidence_matrix = spotit_z3(symbols_per_card) for row in incidence_matrix: print(row) Results $python spotit_z3.py 3 [0, 0, 1, 1, 0, 1, 0] [0, 0, 0, 0, 1, 1, 1] [0, 1, 0, 1, 0, 0, 1] [1, 1, 0, 0, 0, 1, 0] [0, 1, 1, 0, 1, 0, 0] [1, 0, 0, 1, 1, 0, 0] [1, 0, 1, 0, 0, 0, 1] python spotit_z3.py 3 1.12s user 0.06s system 96% cpu 1.225 total $ time python3 spotit_z3.py 4 [0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0] [0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0] [0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1] [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0] [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1] [0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0] [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1] [0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0] [0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0] [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1] [1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0] [1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0] [1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0] python spotit_z3.py 4 664.62s user 0.15s system 99% cpu 11:04.88 total $ time python3 spotit_z3.py 5 [1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0] [0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0] [0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0] [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0] [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0] [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1] [0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0] [0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0] [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1] [1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0] [0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0] [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0] [0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1] [1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1] [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0] [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0] [0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1] [1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0] python spotit_z3.py 5 1162.72s user 20.34s system 99% cpu 19:43.39 total $ time python3 spotit_z3.py 8 <I killed it after 14 hours of run time.>
I very much like this thread. I build this github python project with parts of this code here to draw custom cards as png (so one can order custom card games in the internet). https://github.com/plagtag/ProjectiveGeometry-Game
I wrote an article about how to generate this kind of decks, with code in Perl. The code is not optimized but it's at least capable of generating decks of "reasonable" orders... and some more. Here's an example with order 8, which has to consider a slightly more complicated underlying math, because 8 is not prime although a valid order for generating these kind of decks. See above or the article for a more detailed explanation, below if you just want to generate a slightly more difficult Spot-It :-) $ time pg2 8 elements in field: 8 0. (1, 9, 17, 25, 33, 41, 49, 57, 65) 1. (0, 9, 10, 11, 12, 13, 14, 15, 16) 2. (2, 9, 18, 27, 36, 45, 54, 63, 72) 3. (6, 9, 22, 26, 37, 43, 56, 60, 71) 4. (7, 9, 23, 32, 34, 46, 52, 59, 69) 5. (8, 9, 24, 30, 35, 42, 55, 61, 68) 6. (3, 9, 19, 29, 39, 44, 50, 64, 70) 7. (4, 9, 20, 31, 38, 48, 53, 58, 67) 8. (5, 9, 21, 28, 40, 47, 51, 62, 66) 9. (0, 1, 2, 3, 4, 5, 6, 7, 8) 10. (1, 10, 18, 26, 34, 42, 50, 58, 66) 11. (1, 14, 22, 30, 38, 46, 54, 62, 70) 12. (1, 15, 23, 31, 39, 47, 55, 63, 71) 13. (1, 16, 24, 32, 40, 48, 56, 64, 72) 14. (1, 11, 19, 27, 35, 43, 51, 59, 67) 15. (1, 12, 20, 28, 36, 44, 52, 60, 68) 16. (1, 13, 21, 29, 37, 45, 53, 61, 69) 17. (0, 17, 18, 19, 20, 21, 22, 23, 24) 18. (2, 10, 17, 28, 35, 46, 53, 64, 71) 19. (6, 14, 17, 29, 34, 48, 51, 63, 68) 20. (7, 15, 17, 26, 40, 44, 54, 61, 67) 21. (8, 16, 17, 27, 38, 47, 50, 60, 69) 22. (3, 11, 17, 31, 37, 42, 52, 62, 72) 23. (4, 12, 17, 30, 39, 45, 56, 59, 66) 24. (5, 13, 17, 32, 36, 43, 55, 58, 70) 25. (0, 49, 50, 51, 52, 53, 54, 55, 56) 26. (3, 10, 20, 30, 40, 43, 49, 63, 69) 27. (2, 14, 21, 32, 39, 42, 49, 60, 67) 28. (8, 15, 18, 28, 37, 48, 49, 59, 70) 29. (6, 16, 19, 31, 36, 46, 49, 61, 66) 30. (5, 11, 23, 26, 38, 45, 49, 64, 68) 31. (7, 12, 22, 29, 35, 47, 49, 58, 72) 32. (4, 13, 24, 27, 34, 44, 49, 62, 71) 33. (0, 57, 58, 59, 60, 61, 62, 63, 64) 34. (4, 10, 19, 32, 37, 47, 54, 57, 68) 35. (5, 14, 18, 31, 35, 44, 56, 57, 69) 36. (2, 15, 24, 29, 38, 43, 52, 57, 66) 37. (3, 16, 22, 28, 34, 45, 55, 57, 67) 38. (7, 11, 21, 30, 36, 48, 50, 57, 71) 39. (6, 12, 23, 27, 40, 42, 53, 57, 70) 40. (8, 13, 20, 26, 39, 46, 51, 57, 72) 41. (0, 65, 66, 67, 68, 69, 70, 71, 72) 42. (5, 10, 22, 27, 39, 48, 52, 61, 65) 43. (3, 14, 24, 26, 36, 47, 53, 59, 65) 44. (6, 15, 20, 32, 35, 45, 50, 62, 65) 45. (2, 16, 23, 30, 37, 44, 51, 58, 65) 46. (4, 11, 18, 29, 40, 46, 55, 60, 65) 47. (8, 12, 21, 31, 34, 43, 54, 64, 65) 48. (7, 13, 19, 28, 38, 42, 56, 63, 65) 49. (0, 25, 26, 27, 28, 29, 30, 31, 32) 50. (6, 10, 21, 25, 38, 44, 55, 59, 72) 51. (8, 14, 19, 25, 40, 45, 52, 58, 71) 52. (4, 15, 22, 25, 36, 42, 51, 64, 69) 53. (7, 16, 18, 25, 39, 43, 53, 62, 68) 54. (2, 11, 20, 25, 34, 47, 56, 61, 70) 55. (5, 12, 24, 25, 37, 46, 50, 63, 67) 56. (3, 13, 23, 25, 35, 48, 54, 60, 66) 57. (0, 33, 34, 35, 36, 37, 38, 39, 40) 58. (7, 10, 24, 31, 33, 45, 51, 60, 70) 59. (4, 14, 23, 28, 33, 43, 50, 61, 72) 60. (3, 15, 21, 27, 33, 46, 56, 58, 68) 61. (5, 16, 20, 29, 33, 42, 54, 59, 71) 62. (8, 11, 22, 32, 33, 44, 53, 63, 66) 63. (2, 12, 19, 26, 33, 48, 55, 62, 69) 64. (6, 13, 18, 30, 33, 47, 52, 64, 67) 65. (0, 41, 42, 43, 44, 45, 46, 47, 48) 66. (8, 10, 23, 29, 36, 41, 56, 62, 67) 67. (7, 14, 20, 27, 37, 41, 55, 64, 66) 68. (5, 15, 19, 30, 34, 41, 53, 60, 72) 69. (4, 16, 21, 26, 35, 41, 52, 63, 70) 70. (6, 11, 24, 28, 39, 41, 54, 58, 69) 71. (3, 12, 18, 32, 38, 41, 51, 61, 71) 72. (2, 13, 22, 31, 40, 41, 50, 59, 68) errors in check: 0 real 0m0.303s user 0m0.200s sys 0m0.016s Each identifier from 0 to 72 can be read both as a card identifier and as a picture identifier. For example, the last row means that: card 72 contains pictures 2, 13, 22, ..., 59, 68, AND picture 72 appears in cards 2, 13, 22, ..., 59, and 68.
I wrote the following code to calculate the cards. The idea is to create the first card with n images on it. If the difference of every pair of image indexes is unique then the rest of the cards can be generated trivially, by increasing each index with the same value modulo m = n * n - n + 1 static public int[] Backtrack(int n) { int m = n * n - n + 1; int[] Check = new int[m]; int C = 1; int[] T = new int[n]; int _p = 2; T[1] = 1; if (n > 2) T[2] = 1; else return T; while (_p >= 2) { T[_p]++; if (T[_p] == m) { _p--; continue; } bool good = true; C++; for (int i = 0; i <= _p; i++) { for (int j = 0; j < i; j++) { int x = (T[i] - T[j] + m) % m; if (Check[x] == C || Check[m - x] == C)//x cannot be equal to m-x as m is odd. good = false; Check[m - x] = C; Check[x] = C; } } if (good) { _p++; if (_p == n) { _p--; return T; } T[_p] = T[_p - 1]; } } return new int[] { }; } static void Main(string[] args) { for (int N = 2; N < 11; N++) { var X = Backtrack(N); if (X.Length > 0) { int K = N * N - N + 1; Console.WriteLine("Cards: {0} Order {1}:", K, N - 1); int C = 0; for (int j = 0; j < K; j++) { Console.Write("Card {0:000}:", C++); for (int i = 0; i < N; i++) { var t = (X[i] + j) % K; if (j != 0 && Array.Exists(X, x => (x == t))) Console.ForegroundColor = ConsoleColor.Green; Console.Write("\t{0}", t); Console.ResetColor(); } Console.WriteLine(); } } } } output: Cards: 3 Order 1: Card 000: 0 1 Card 001: 1 2 Card 002: 2 0 Cards: 7 Order 2: Card 000: 0 1 3 Card 001: 1 2 4 Card 002: 2 3 5 Card 003: 3 4 6 Card 004: 4 5 0 Card 005: 5 6 1 Card 006: 6 0 2 Cards: 13 Order 3: Card 000: 0 1 3 9 Card 001: 1 2 4 10 Card 002: 2 3 5 11 Card 003: 3 4 6 12 Card 004: 4 5 7 0 Card 005: 5 6 8 1 Card 006: 6 7 9 2 Card 007: 7 8 10 3 Card 008: 8 9 11 4 Card 009: 9 10 12 5 Card 010: 10 11 0 6 Card 011: 11 12 1 7 Card 012: 12 0 2 8 Cards: 21 Order 4: Card 000: 0 1 4 14 16 Card 001: 1 2 5 15 17 Card 002: 2 3 6 16 18 Card 003: 3 4 7 17 19 Card 004: 4 5 8 18 20 Card 005: 5 6 9 19 0 Card 006: 6 7 10 20 1 Card 007: 7 8 11 0 2 Card 008: 8 9 12 1 3 Card 009: 9 10 13 2 4 Card 010: 10 11 14 3 5 Card 011: 11 12 15 4 6 Card 012: 12 13 16 5 7 Card 013: 13 14 17 6 8 Card 014: 14 15 18 7 9 Card 015: 15 16 19 8 10 Card 016: 16 17 20 9 11 Card 017: 17 18 0 10 12 Card 018: 18 19 1 11 13 Card 019: 19 20 2 12 14 Card 020: 20 0 3 13 15 Cards: 31 Order 5: Card 000: 0 1 3 8 12 18 Card 001: 1 2 4 9 13 19 Card 002: 2 3 5 10 14 20 Card 003: 3 4 6 11 15 21 Card 004: 4 5 7 12 16 22 Card 005: 5 6 8 13 17 23 Card 006: 6 7 9 14 18 24 Card 007: 7 8 10 15 19 25 Card 008: 8 9 11 16 20 26 Card 009: 9 10 12 17 21 27 Card 010: 10 11 13 18 22 28 Card 011: 11 12 14 19 23 29 Card 012: 12 13 15 20 24 30 Card 013: 13 14 16 21 25 0 Card 014: 14 15 17 22 26 1 Card 015: 15 16 18 23 27 2 Card 016: 16 17 19 24 28 3 Card 017: 17 18 20 25 29 4 Card 018: 18 19 21 26 30 5 Card 019: 19 20 22 27 0 6 Card 020: 20 21 23 28 1 7 Card 021: 21 22 24 29 2 8 Card 022: 22 23 25 30 3 9 Card 023: 23 24 26 0 4 10 Card 024: 24 25 27 1 5 11 Card 025: 25 26 28 2 6 12 Card 026: 26 27 29 3 7 13 Card 027: 27 28 30 4 8 14 Card 028: 28 29 0 5 9 15 Card 029: 29 30 1 6 10 16 Card 030: 30 0 2 7 11 17 Cards: 57 Order 7: Card 000: 0 1 3 13 32 36 43 52 Card 001: 1 2 4 14 33 37 44 53 Card 002: 2 3 5 15 34 38 45 54 Card 003: 3 4 6 16 35 39 46 55 Card 004: 4 5 7 17 36 40 47 56 Card 005: 5 6 8 18 37 41 48 0 Card 006: 6 7 9 19 38 42 49 1 Card 007: 7 8 10 20 39 43 50 2 Card 008: 8 9 11 21 40 44 51 3 Card 009: 9 10 12 22 41 45 52 4 Card 010: 10 11 13 23 42 46 53 5 Card 011: 11 12 14 24 43 47 54 6 Card 012: 12 13 15 25 44 48 55 7 Card 013: 13 14 16 26 45 49 56 8 Card 014: 14 15 17 27 46 50 0 9 Card 015: 15 16 18 28 47 51 1 10 Card 016: 16 17 19 29 48 52 2 11 Card 017: 17 18 20 30 49 53 3 12 Card 018: 18 19 21 31 50 54 4 13 Card 019: 19 20 22 32 51 55 5 14 Card 020: 20 21 23 33 52 56 6 15 Card 021: 21 22 24 34 53 0 7 16 Card 022: 22 23 25 35 54 1 8 17 Card 023: 23 24 26 36 55 2 9 18 Card 024: 24 25 27 37 56 3 10 19 Card 025: 25 26 28 38 0 4 11 20 Card 026: 26 27 29 39 1 5 12 21 Card 027: 27 28 30 40 2 6 13 22 Card 028: 28 29 31 41 3 7 14 23 Card 029: 29 30 32 42 4 8 15 24 Card 030: 30 31 33 43 5 9 16 25 Card 031: 31 32 34 44 6 10 17 26 Card 032: 32 33 35 45 7 11 18 27 Card 033: 33 34 36 46 8 12 19 28 Card 034: 34 35 37 47 9 13 20 29 Card 035: 35 36 38 48 10 14 21 30 Card 036: 36 37 39 49 11 15 22 31 Card 037: 37 38 40 50 12 16 23 32 Card 038: 38 39 41 51 13 17 24 33 Card 039: 39 40 42 52 14 18 25 34 Card 040: 40 41 43 53 15 19 26 35 Card 041: 41 42 44 54 16 20 27 36 Card 042: 42 43 45 55 17 21 28 37 Card 043: 43 44 46 56 18 22 29 38 Card 044: 44 45 47 0 19 23 30 39 Card 045: 45 46 48 1 20 24 31 40 Card 046: 46 47 49 2 21 25 32 41 Card 047: 47 48 50 3 22 26 33 42 Card 048: 48 49 51 4 23 27 34 43 Card 049: 49 50 52 5 24 28 35 44 Card 050: 50 51 53 6 25 29 36 45 Card 051: 51 52 54 7 26 30 37 46 Card 052: 52 53 55 8 27 31 38 47 Card 053: 53 54 56 9 28 32 39 48 Card 054: 54 55 0 10 29 33 40 49 Card 055: 55 56 1 11 30 34 41 50 Card 056: 56 0 2 12 31 35 42 51 Cards: 73 Order 8: Card 000: 0 1 3 7 15 31 36 54 63 Card 001: 1 2 4 8 16 32 37 55 64 Card 002: 2 3 5 9 17 33 38 56 65 Card 003: 3 4 6 10 18 34 39 57 66 Card 004: 4 5 7 11 19 35 40 58 67 Card 005: 5 6 8 12 20 36 41 59 68 Card 006: 6 7 9 13 21 37 42 60 69 Card 007: 7 8 10 14 22 38 43 61 70 Card 008: 8 9 11 15 23 39 44 62 71 Card 009: 9 10 12 16 24 40 45 63 72 Card 010: 10 11 13 17 25 41 46 64 0 Card 011: 11 12 14 18 26 42 47 65 1 Card 012: 12 13 15 19 27 43 48 66 2 Card 013: 13 14 16 20 28 44 49 67 3 Card 014: 14 15 17 21 29 45 50 68 4 Card 015: 15 16 18 22 30 46 51 69 5 Card 016: 16 17 19 23 31 47 52 70 6 Card 017: 17 18 20 24 32 48 53 71 7 Card 018: 18 19 21 25 33 49 54 72 8 Card 019: 19 20 22 26 34 50 55 0 9 Card 020: 20 21 23 27 35 51 56 1 10 Card 021: 21 22 24 28 36 52 57 2 11 Card 022: 22 23 25 29 37 53 58 3 12 Card 023: 23 24 26 30 38 54 59 4 13 Card 024: 24 25 27 31 39 55 60 5 14 Card 025: 25 26 28 32 40 56 61 6 15 Card 026: 26 27 29 33 41 57 62 7 16 Card 027: 27 28 30 34 42 58 63 8 17 Card 028: 28 29 31 35 43 59 64 9 18 Card 029: 29 30 32 36 44 60 65 10 19 Card 030: 30 31 33 37 45 61 66 11 20 Card 031: 31 32 34 38 46 62 67 12 21 Card 032: 32 33 35 39 47 63 68 13 22 Card 033: 33 34 36 40 48 64 69 14 23 Card 034: 34 35 37 41 49 65 70 15 24 Card 035: 35 36 38 42 50 66 71 16 25 Card 036: 36 37 39 43 51 67 72 17 26 Card 037: 37 38 40 44 52 68 0 18 27 Card 038: 38 39 41 45 53 69 1 19 28 Card 039: 39 40 42 46 54 70 2 20 29 Card 040: 40 41 43 47 55 71 3 21 30 Card 041: 41 42 44 48 56 72 4 22 31 Card 042: 42 43 45 49 57 0 5 23 32 Card 043: 43 44 46 50 58 1 6 24 33 Card 044: 44 45 47 51 59 2 7 25 34 Card 045: 45 46 48 52 60 3 8 26 35 Card 046: 46 47 49 53 61 4 9 27 36 Card 047: 47 48 50 54 62 5 10 28 37 Card 048: 48 49 51 55 63 6 11 29 38 Card 049: 49 50 52 56 64 7 12 30 39 Card 050: 50 51 53 57 65 8 13 31 40 Card 051: 51 52 54 58 66 9 14 32 41 Card 052: 52 53 55 59 67 10 15 33 42 Card 053: 53 54 56 60 68 11 16 34 43 Card 054: 54 55 57 61 69 12 17 35 44 Card 055: 55 56 58 62 70 13 18 36 45 Card 056: 56 57 59 63 71 14 19 37 46 Card 057: 57 58 60 64 72 15 20 38 47 Card 058: 58 59 61 65 0 16 21 39 48 Card 059: 59 60 62 66 1 17 22 40 49 Card 060: 60 61 63 67 2 18 23 41 50 Card 061: 61 62 64 68 3 19 24 42 51 Card 062: 62 63 65 69 4 20 25 43 52 Card 063: 63 64 66 70 5 21 26 44 53 Card 064: 64 65 67 71 6 22 27 45 54 Card 065: 65 66 68 72 7 23 28 46 55 Card 066: 66 67 69 0 8 24 29 47 56 Card 067: 67 68 70 1 9 25 30 48 57 Card 068: 68 69 71 2 10 26 31 49 58 Card 069: 69 70 72 3 11 27 32 50 59 Card 070: 70 71 0 4 12 28 33 51 60 Card 071: 71 72 1 5 13 29 34 52 61 Card 072: 72 0 2 6 14 30 35 53 62 Cards: 91 Order 9: Card 000: 0 1 3 9 27 49 56 61 77 81 Card 001: 1 2 4 10 28 50 57 62 78 82 Card 002: 2 3 5 11 29 51 58 63 79 83 Card 003: 3 4 6 12 30 52 59 64 80 84 Card 004: 4 5 7 13 31 53 60 65 81 85 Card 005: 5 6 8 14 32 54 61 66 82 86 Card 006: 6 7 9 15 33 55 62 67 83 87 Card 007: 7 8 10 16 34 56 63 68 84 88 Card 008: 8 9 11 17 35 57 64 69 85 89 Card 009: 9 10 12 18 36 58 65 70 86 90 Card 010: 10 11 13 19 37 59 66 71 87 0 Card 011: 11 12 14 20 38 60 67 72 88 1 Card 012: 12 13 15 21 39 61 68 73 89 2 Card 013: 13 14 16 22 40 62 69 74 90 3 Card 014: 14 15 17 23 41 63 70 75 0 4 Card 015: 15 16 18 24 42 64 71 76 1 5 Card 016: 16 17 19 25 43 65 72 77 2 6 Card 017: 17 18 20 26 44 66 73 78 3 7 Card 018: 18 19 21 27 45 67 74 79 4 8 Card 019: 19 20 22 28 46 68 75 80 5 9 Card 020: 20 21 23 29 47 69 76 81 6 10 Card 021: 21 22 24 30 48 70 77 82 7 11 Card 022: 22 23 25 31 49 71 78 83 8 12 Card 023: 23 24 26 32 50 72 79 84 9 13 Card 024: 24 25 27 33 51 73 80 85 10 14 Card 025: 25 26 28 34 52 74 81 86 11 15 Card 026: 26 27 29 35 53 75 82 87 12 16 Card 027: 27 28 30 36 54 76 83 88 13 17 Card 028: 28 29 31 37 55 77 84 89 14 18 Card 029: 29 30 32 38 56 78 85 90 15 19 Card 030: 30 31 33 39 57 79 86 0 16 20 Card 031: 31 32 34 40 58 80 87 1 17 21 Card 032: 32 33 35 41 59 81 88 2 18 22 Card 033: 33 34 36 42 60 82 89 3 19 23 Card 034: 34 35 37 43 61 83 90 4 20 24 Card 035: 35 36 38 44 62 84 0 5 21 25 Card 036: 36 37 39 45 63 85 1 6 22 26 Card 037: 37 38 40 46 64 86 2 7 23 27 Card 038: 38 39 41 47 65 87 3 8 24 28 Card 039: 39 40 42 48 66 88 4 9 25 29 Card 040: 40 41 43 49 67 89 5 10 26 30 Card 041: 41 42 44 50 68 90 6 11 27 31 Card 042: 42 43 45 51 69 0 7 12 28 32 Card 043: 43 44 46 52 70 1 8 13 29 33 Card 044: 44 45 47 53 71 2 9 14 30 34 Card 045: 45 46 48 54 72 3 10 15 31 35 Card 046: 46 47 49 55 73 4 11 16 32 36 Card 047: 47 48 50 56 74 5 12 17 33 37 Card 048: 48 49 51 57 75 6 13 18 34 38 Card 049: 49 50 52 58 76 7 14 19 35 39 Card 050: 50 51 53 59 77 8 15 20 36 40 Card 051: 51 52 54 60 78 9 16 21 37 41 Card 052: 52 53 55 61 79 10 17 22 38 42 Card 053: 53 54 56 62 80 11 18 23 39 43 Card 054: 54 55 57 63 81 12 19 24 40 44 Card 055: 55 56 58 64 82 13 20 25 41 45 Card 056: 56 57 59 65 83 14 21 26 42 46 Card 057: 57 58 60 66 84 15 22 27 43 47 Card 058: 58 59 61 67 85 16 23 28 44 48 Card 059: 59 60 62 68 86 17 24 29 45 49 Card 060: 60 61 63 69 87 18 25 30 46 50 Card 061: 61 62 64 70 88 19 26 31 47 51 Card 062: 62 63 65 71 89 20 27 32 48 52 Card 063: 63 64 66 72 90 21 28 33 49 53 Card 064: 64 65 67 73 0 22 29 34 50 54 Card 065: 65 66 68 74 1 23 30 35 51 55 Card 066: 66 67 69 75 2 24 31 36 52 56 Card 067: 67 68 70 76 3 25 32 37 53 57 Card 068: 68 69 71 77 4 26 33 38 54 58 Card 069: 69 70 72 78 5 27 34 39 55 59 Card 070: 70 71 73 79 6 28 35 40 56 60 Card 071: 71 72 74 80 7 29 36 41 57 61 Card 072: 72 73 75 81 8 30 37 42 58 62 Card 073: 73 74 76 82 9 31 38 43 59 63 Card 074: 74 75 77 83 10 32 39 44 60 64 Card 075: 75 76 78 84 11 33 40 45 61 65 Card 076: 76 77 79 85 12 34 41 46 62 66 Card 077: 77 78 80 86 13 35 42 47 63 67 Card 078: 78 79 81 87 14 36 43 48 64 68 Card 079: 79 80 82 88 15 37 44 49 65 69 Card 080: 80 81 83 89 16 38 45 50 66 70 Card 081: 81 82 84 90 17 39 46 51 67 71 Card 082: 82 83 85 0 18 40 47 52 68 72 Card 083: 83 84 86 1 19 41 48 53 69 73 Card 084: 84 85 87 2 20 42 49 54 70 74 Card 085: 85 86 88 3 21 43 50 55 71 75 Card 086: 86 87 89 4 22 44 51 56 72 76 Card 087: 87 88 90 5 23 45 52 57 73 77 Card 088: 88 89 0 6 24 46 53 58 74 78 Card 089: 89 90 1 7 25 47 54 59 75 79 Card 090: 90 0 2 8 26 48 55 60 76 80