I noticed that our electronic lock at work didn't care if my passcode was entered in the middle of other numbers, it still accepted it.
Got me thinking, what is the shortest string I could come up that held every combo of [0-9][0-9][0-9][0-9]
Basic strategy: Get the next number. Check if that number already exists in our string. If not, add it. Clean up some excess at the end.
The sequence of 000000010002 already contains 0010, 0100 and 1000 so there is no need to duplicate it.
My first pass added numbers in natural order and the resulting string was 10097 bytes long.
Adding numbers in random order only made things MUCH worse.
Heres the challenge: Can you get below 10097?
(I'm not worried about someone using this for illegal purposes. On my keypad it would take almost an hour to enter that sequence, though I suppose it is better than four hours for the 40000 keystrokes that entering them one after the other would take.
/* Try to generate the shortest string that will open up an electronic
keypad, assuming that digits can be entered in the middle of a stream.
example: If the door unlock code is 1701
then 12341701496 must work to unlock the door.
If the lock requires hitting # or other special key after the code,
then it breaks.
(Please excuse the horrid C. Its been a while since I've worked in C and
I kind of did this as a refresher.)
Code released into public domain.
*/
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <time.h>
#define TRUE 1
#define FALSE 0
#define BOOL int
/* Set things up for a four digit code */
#define LASTNUM 9999
#define PLACES 4
#define FORMAT "%04d"
#define MAXLEN ( (PLACES) * (LASTNUM + 1) +1)
#define RANDOM FALSE /* Randomize the numbers each time? */
/* Number of passes per run. If RANDOM is false, then should be 1 */
#define PASSES 1
/* Quick and dirty version of malloc. Init string. */
char *m_str(size_t size)
{
char *d;
d = malloc(size);
if (d == NULL)
{
printf("Get rid of the VIC 20. Memory low.\n");
exit(1);
}
d[0] = 0;
return(d);
}
/* Trim down any digit that appears more than [count] times.
* For example: 0800 and 0001 would result in 08000001.
* This can be safely turned into 080001
*/
char *strip(char *s, int count)
{
int j;
char *d; /* Destination */
/* Named after x86 assembly language registers */
long si; /* Src index */
long di; /* Dest index */
BOOL is_ok;
d = m_str(MAXLEN +1);
di = 0;
si = 0;
while (s[si] != 0) /* Loop to end of string */
{
j = 0;
is_ok = FALSE;
while (j < count)
{
/* If the character does NOT match the character that comes next */
is_ok = ( (s[si + j] != s[si + j+1]) || is_ok);
j++;
}
if (is_ok) {
d[di] = s[si];
di++;
}
si++;
}
d[di] = 0;
return d;
}
void tell_me(char *s, int i)
{
printf("Result is: %s [Pass %4d] \n",s, i);
printf("Length:%7d Pass %4d\n",strlen(s), i);
printf("\n");
}
char* doit(void)
{
int i;
char *loc;
char *n;
int where;
char *list[LASTNUM+1];
char *compact;
compact = m_str(MAXLEN);
srand( (unsigned int)time( NULL ) );
/* First create the array */
/* printf("Creating array\n"); */
for (i = 0; i < LASTNUM + 1; i++)
{
n = m_str(PLACES+1);
sprintf(n, FORMAT, i);
list[i] = n;
}
#if RANDOM
/* Randomize the array */
/* printf("Randomizing array\n"); */
for (i = 0; i < LASTNUM + 1; i++)
{
where = rand() % LASTNUM;
n = list[where];
list[where] = list[i];
list[i] = n;
}
#endif
/* Build the string */
/* printf("Building string\n"); */
for (i = 0; i < LASTNUM + 1; i++)
{
n = list[i];
loc = strstr(compact, n);
if (loc == NULL) { /* Not found */
strcat(compact, n);
}
}
loc = strip(compact, PLACES);
for (i = 0; i < LASTNUM + 1; i++)
{
free(list[i]);
}
free(compact);
return loc;
}
int main(void)
{
int i;
char *r;
for (i = 0; i < PASSES; i++)
{
r = doit();
tell_me(r, i);
free(r);
}
return(0);
}
Output, folded for readability. If PASSES > 1 then the output is very grep and sort friendly.
Result is: 000010002000300040005000600070008000900110012001300140015001600170018
00190021002200230024002500260027002800290031003200330034003500360037003800390041
00420043004400450046004700480049005100520053005400550056005700580059006100620063
00640065006600670068006900710072007300740075007600770078007900810082008300840085
00860087008800890091009200930094009500960097009800990101010201030104010501060107
01080109011101120113011401150116011701180119012101220123012401250126012701280129
01310132013301340135013601370138013901410142014301440145014601470148014901510152
01530154015501560157015801590161016201630164016501660167016801690171017201730174
01750176017701780179018101820183018401850186018701880189019101920193019401950196
01970198019902020203020402050206020702080209021102120213021402150216021702180219
02210222022302240225022602270228022902310232023302340235023602370238023902410242
02430244024502460247024802490251025202530254025502560257025802590261026202630264
02650266026702680269027102720273027402750276027702780279028102820283028402850286
02870288028902910292029302940295029602970298029903030304030503060307030803090311
03120313031403150316031703180319032103220323032403250326032703280329033103320333
03340335033603370338033903410342034303440345034603470348034903510352035303540355
03560357035803590361036203630364036503660367036803690371037203730374037503760377
03780379038103820383038403850386038703880389039103920393039403950396039703980399
04040405040604070408040904110412041304140415041604170418041904210422042304240425
04260427042804290431043204330434043504360437043804390441044204430444044504460447
04480449045104520453045404550456045704580459046104620463046404650466046704680469
04710472047304740475047604770478047904810482048304840485048604870488048904910492
04930494049504960497049804990505050605070508050905110512051305140515051605170518
05190521052205230524052505260527052805290531053205330534053505360537053805390541
05420543054405450546054705480549055105520553055405550556055705580559056105620563
05640565056605670568056905710572057305740575057605770578057905810582058305840585
05860587058805890591059205930594059505960597059805990606060706080609061106120613
06140615061606170618061906210622062306240625062606270628062906310632063306340635
06360637063806390641064206430644064506460647064806490651065206530654065506560657
06580659066106620663066406650666066706680669067106720673067406750676067706780679
06810682068306840685068606870688068906910692069306940695069606970698069907070708
07090711071207130714071507160717071807190721072207230724072507260727072807290731
07320733073407350736073707380739074107420743074407450746074707480749075107520753
07540755075607570758075907610762076307640765076607670768076907710772077307740775
07760777077807790781078207830784078507860787078807890791079207930794079507960797
07980799080808090811081208130814081508160817081808190821082208230824082508260827
08280829083108320833083408350836083708380839084108420843084408450846084708480849
08510852085308540855085608570858085908610862086308640865086608670868086908710872
08730874087508760877087808790881088208830884088508860887088808890891089208930894
08950896089708980899090909110912091309140915091609170918091909210922092309240925
09260927092809290931093209330934093509360937093809390941094209430944094509460947
09480949095109520953095409550956095709580959096109620963096409650966096709680969
09710972097309740975097609770978097909810982098309840985098609870988098909910992
09930994099509960997099809991111211131114111511161117111811191122112311241125112
61127112811291132113311341135113611371138113911421143114411451146114711481149115
21153115411551156115711581159116211631164116511661167116811691172117311741175117
61177117811791182118311841185118611871188118911921193119411951196119711981199121
21213121412151216121712181219122212231224122512261227122812291232123312341235123
61237123812391242124312441245124612471248124912521253125412551256125712581259126
21263126412651266126712681269127212731274127512761277127812791282128312841285128
61287128812891292129312941295129612971298129913131314131513161317131813191322132
31324132513261327132813291332133313341335133613371338133913421343134413451346134
71348134913521353135413551356135713581359136213631364136513661367136813691372137
31374137513761377137813791382138313841385138613871388138913921393139413951396139
71398139914141415141614171418141914221423142414251426142714281429143214331434143
51436143714381439144214431444144514461447144814491452145314541455145614571458145
91462146314641465146614671468146914721473147414751476147714781479148214831484148
51486148714881489149214931494149514961497149814991515151615171518151915221523152
41525152615271528152915321533153415351536153715381539154215431544154515461547154
81549155215531554155515561557155815591562156315641565156615671568156915721573157
41575157615771578157915821583158415851586158715881589159215931594159515961597159
81599161616171618161916221623162416251626162716281629163216331634163516361637163
81639164216431644164516461647164816491652165316541655165616571658165916621663166
41665166616671668166916721673167416751676167716781679168216831684168516861687168
81689169216931694169516961697169816991717171817191722172317241725172617271728172
91732173317341735173617371738173917421743174417451746174717481749175217531754175
51756175717581759176217631764176517661767176817691772177317741775177617771778177
91782178317841785178617871788178917921793179417951796179717981799181818191822182
31824182518261827182818291832183318341835183618371838183918421843184418451846184
71848184918521853185418551856185718581859186218631864186518661867186818691872187
31874187518761877187818791882188318841885188618871888188918921893189418951896189
71898189919191922192319241925192619271928192919321933193419351936193719381939194
21943194419451946194719481949195219531954195519561957195819591962196319641965196
61967196819691972197319741975197619771978197919821983198419851986198719881989199
21993199419951996199719981999222232224222522262227222822292233223422352236223722
38223922432244224522462247224822492253225422552256225722582259226322642265226622
67226822692273227422752276227722782279228322842285228622872288228922932294229522
96229722982299232323242325232623272328232923332334233523362337233823392343234423
45234623472348234923532354235523562357235823592363236423652366236723682369237323
74237523762377237823792383238423852386238723882389239323942395239623972398239924
24242524262427242824292433243424352436243724382439244324442445244624472448244924
53245424552456245724582459246324642465246624672468246924732474247524762477247824
79248324842485248624872488248924932494249524962497249824992525252625272528252925
33253425352536253725382539254325442545254625472548254925532554255525562557255825
59256325642565256625672568256925732574257525762577257825792583258425852586258725
88258925932594259525962597259825992626262726282629263326342635263626372638263926
43264426452646264726482649265326542655265626572658265926632664266526662667266826
69267326742675267626772678267926832684268526862687268826892693269426952696269726
98269927272728272927332734273527362737273827392743274427452746274727482749275327
54275527562757275827592763276427652766276727682769277327742775277627772778277927
83278427852786278727882789279327942795279627972798279928282829283328342835283628
37283828392843284428452846284728482849285328542855285628572858285928632864286528
66286728682869287328742875287628772878287928832884288528862887288828892893289428
95289628972898289929292933293429352936293729382939294329442945294629472948294929
53295429552956295729582959296329642965296629672968296929732974297529762977297829
79298329842985298629872988298929932994299529962997299829993333433353336333733383
33933443345334633473348334933543355335633573358335933643365336633673368336933743
37533763377337833793384338533863387338833893394339533963397339833993434343534363
43734383439344434453446344734483449345434553456345734583459346434653466346734683
46934743475347634773478347934843485348634873488348934943495349634973498349935353
53635373538353935443545354635473548354935543555355635573558355935643565356635673
56835693574357535763577357835793584358535863587358835893594359535963597359835993
63636373638363936443645364636473648364936543655365636573658365936643665366636673
66836693674367536763677367836793684368536863687368836893694369536963697369836993
73737383739374437453746374737483749375437553756375737583759376437653766376737683
76937743775377637773778377937843785378637873788378937943795379637973798379938383
83938443845384638473848384938543855385638573858385938643865386638673868386938743
87538763877387838793884388538863887388838893894389538963897389838993939394439453
94639473948394939543955395639573958395939643965396639673968396939743975397639773
97839793984398539863987398839893994399539963997399839994444544464447444844494455
44564457445844594465446644674468446944754476447744784479448544864487448844894495
44964497449844994545454645474548454945554556455745584559456545664567456845694575
45764577457845794585458645874588458945954596459745984599464646474648464946554656
46574658465946654666466746684669467546764677467846794685468646874688468946954696
46974698469947474748474947554756475747584759476547664767476847694775477647774778
47794785478647874788478947954796479747984799484848494855485648574858485948654866
48674868486948754876487748784879488548864887488848894895489648974898489949494955
49564957495849594965496649674968496949754976497749784979498549864987498849894995
49964997499849995555655575558555955665567556855695576557755785579558655875588558
95596559755985599565656575658565956665667566856695676567756785679568656875688568
95696569756985699575757585759576657675768576957765777577857795786578757885789579
65797579857995858585958665867586858695876587758785879588658875888588958965897589
85899595959665967596859695976597759785979598659875988598959965997599859996666766
68666966776678667966876688668966976698669967676768676967776778677967876788678967
97679867996868686968776878687968876888688968976898689969696977697869796987698869
89699769986999777787779778877897798779978787879788878897898789979797988798979987
9998888988988899898989999000 [Pass 0]
Length: 10097 Pass 0