Levenshtein distance & OEIS (Cops)

16

0

This is the Cop post. The Robber post is here.


Your task is to take an integer input N and output the Nth digit in the sequence OEIS A002942.

The sequence consists of the square numbers written backwards:

1, 4, 9, 61, 52, 63, 94, 46, 18, 1, 121, 441, ...

Note that leading zeros are trimmed away (100 becomes 1, not 001). Concatenating this into a string (or one long number gives):

1496152639446181121441

You shall output the Nth digit in this string/number. You may choose to take N as 0-indexed or 1-indexed (please state which one you choose).

Test cases (1-indexed):

N = 1,      ==> 1
N = 5,      ==> 1
N = 17,     ==> 1   <- Important test case! It's not zero.
N = 20,     ==> 4
N = 78,     ==> 0
N = 100,    ==> 4

Your code should work for numbers up to N = 2^15 (unless your language can't handles 32 bit integers by default, in which case N can be lower).


Cops:

You must write two functions/programs, in the same language, that do the same thing. You have to post one of the functions/programs, as well as the Levenshtein distance between the two functions/programs you have written. The Levenshtein distance is measured in characters (so addition of a two byte character will give a LD = 1).

The unrevealed code can not be longer than the original solution (but it can be the same size). The robbers will attempt to write a code with the exact Levenshtein distance you gave (it can be different from your unrevealed code, as long as it works).

The winner will be the uncracked submission that has the lowest Levenshtein distance.

You may check the Levenshtein distance here!


If your submission goes uncracked for 7 days then you may reveal the alternative code you have written and mark your submission as safe.


Stewie Griffin

Posted 2017-11-02T14:03:23.480

Reputation: 43 471

Yes, I'll add that to the rules. :) – Stewie Griffin – 2017-11-02T14:09:04.860

You talk about scripts, but I assume this is the default program or function? – Kevin Cruijssen – 2017-11-02T15:02:27.643

Yes, default everything :) – Stewie Griffin – 2017-11-02T15:11:25.823

How are you handling comments and whitespace, I see some weird stuff. – Magic Octopus Urn – 2017-11-02T20:01:54.510

Handing comments and whitespace is part of the cops' challenge. – Stewie Griffin – 2017-11-02T20:07:57.830

1"Your code should work for numbers up to N = 2^15" -> but one of the test cases is larger than that. Is the 274164 case necessary? – Tom Carpenter – 2017-11-04T17:04:16.913

@TomCarpenter what do you gain? I think you need 32bit integers for the squares with N=2^15 already? – Felix Palmen – 2017-11-05T07:28:10.873

Characters rather than bytes: how does that work with RPL? A command is stored using 2.5 bytes, whether it's + or CONVERT, and that 20-bit number has nothing to do with '+' or letters in the word 'convert'. Is it nevertheless the case that DUP 2 (2.5 byte command and 2.5 byte number) differs from DUP2 (another 2.5 byte command) by just 1 (+space) while + and CONVERT (each 2.5 byte command) differ by 7 (change '+' into one letter and add 6 letters)? Even stranger, CONVERT and CONVERTS: a 2.5 byte command and a variable name, 11.5 bytes: distance 1 despite longer by 9 bytes? – Heimdall – 2017-11-18T21:02:30.240

Just to clarify, to edit a program, the program is converted into characters, you edit them, then it's parsed and converted back into its binary representation. – Heimdall – 2017-11-18T21:13:11.823

How about Spectrum BASIC - does PRINT count as 1 character or 5? It's stored as 1 byte and edited (entered/deleted) like a character, that's you can't just delete R to get PINT... It has its own code (8-bit extension of ASCII). A string " PRINT " has LEN 1. – Heimdall – 2017-11-18T21:38:06.390

@Heimdall I don't know! Feel free to post an answer and explain in detail how you calculate the Levenshtein distance. It won't be eligible for the win, sorry... But the fun is in playing :) – Stewie Griffin – 2017-11-18T22:22:24.347

Yes, fun is in the playing. But I can't help being competitive. I guess what makes the most sense is how it's edited. So with Spectrum BASIC I'll assume keywords are single character and with RPL on HP48 I'll assume the commands are made out of individual characters. You asked the question, you decide on interpretation of rules, so I guess it's up to you whether entries in those languages are eligible... – Heimdall – 2017-11-18T23:10:06.473

Answers

6

Haskell, LD = 13, cracked

((snd.span(<'1').reverse.show.(^2)=<<[1..])!!)

Try it online!

I double-checked that leading zeros are trimmed ;)

Explanation:

                    [1..]     -- for each element in [1,2,3,4,5,...]
                 =<<          -- apply the following functions 
             (^2)             -- square [1,4,9,16,25,...]
           show.              -- convert to string ["1","4","9","16","25",...]
       reverse.               -- reverse ["1","4","9","61","52",...,"001",...]
   span(<'1').                -- split into leading zeros and remainder [("","1"),("","4"),...,("00","1"),...]
  snd.                        -- only keep remainder ["1","4","9","61","52",...,"1",...]
                              -- and concatenate the result "1496152..."
((                       )!!) -- index into the sequence

Laikoni

Posted 2017-11-02T14:03:23.480

Reputation: 23 676

2Cracked! – H.PWiz – 2017-11-02T17:02:14.387

3

JavaScript (ES6), LD = 103 (cracked)

Using such a high Levenshtein distance is probably not the best strategy, but let's try it anyway.

n => { for(i = 0, str = ''; i <= n; i++) { str += +[...i * i + ''].reverse().join(''); } return str[n]; }

Test cases

let f =

n => { for(i = 0, str = ''; i <= n; i++) { str += +[...i * i + ''].reverse().join(''); } return str[n]; }

console.log(f(5))      // 1
console.log(f(17))     // 1
console.log(f(20))     // 4
console.log(f(78))     // 0
console.log(f(100))    // 4
console.log(f(274164)) // 1

Intended solution

$=>eval(atob`Wy4uLkFycmF5KCQrMSldLm1hcCgoXyxpKT0+K1suLi5pKmkrJyddLnJldmVyc2UoKS5qb2luYGApLmpvaW5gYFskXQ`)

Encoded part:

[...Array($+1)].map((_,i)=>+[...i*i+''].reverse().join``).join``[$]

Arnauld

Posted 2017-11-02T14:03:23.480

Reputation: 111 334

Does this strip leading 0s after reversing? – Erik the Outgolfer – 2017-11-02T17:45:45.077

@EriktheOutgolfer Yes. The unary + ensures that the reversed string is coerced to a Number. – Arnauld – 2017-11-02T17:54:49.780

1Ohhhh... wow, that's harder than I thought. – Magic Octopus Urn – 2017-11-02T17:55:45.357

Cracked! – Lynn – 2017-11-02T20:28:15.360

3

cQuents 0, LD = 1, Cracked

":\r$*$

Try it online!

I thought this didn't work for leading zeroes, but it actually does - the reverse function in cQuents is coded as int(reversed(str(n))).

Explanation

"         Concatenate sequence together, get nth term in the string instead of the sequence
 :        Mode: Sequence: given input n, output the nth term, 1-indexed
          Each term in the sequences equals:
  \r      reverse(
    $*$           the index * the index
                  or
    $$            the index * the index
                   ) (implicit)

Stephen

Posted 2017-11-02T14:03:23.480

Reputation: 12 293

cracked? – Laikoni – 2017-11-02T15:50:52.473

@Laikoni yep, cQuents does implicit multiplication like, kinda like Mathematica, but you don't need the spaces. Adding an explanation. – Stephen – 2017-11-02T15:52:02.630

3

Python 2, 104 bytes, LD=21 Invalid AND Cracked

d=lambda y:y if'0'!=str(y)[-1]else d(y/10)
lambda n:''.join([str(d(x*x))[::-1]for x in range(1,n)])[n-1]

P.S. Is an unlimited amount of whitespace and commenting allowed? If so this will not be hard to crack.

dylnan

Posted 2017-11-02T14:03:23.480

Reputation: 4 993

1"The unrevealed code can not be longer than the original solution." – Khuldraeseth na'Barya – 2017-11-02T20:10:32.080

@Scrooble I saw that but I don't think it will be hard to make a program that is much shorter than this one. Already been done in python 3 in another answer and it works in python 2 so all they need to add is a bunch of \ns (about 50) – dylnan – 2017-11-02T20:14:37.847

Wouldn't 50 newlines exceed a Levenshtein distance of 21? – Khuldraeseth na'Barya – 2017-11-02T20:21:36.760

@Scrooble You are very right I got confused and was thinking about the problem incorrectly. Thanks – dylnan – 2017-11-02T21:08:45.940

1This seems to error on inputs lower than 5 – Leo – 2017-11-03T00:51:54.693

Anyway, cracked

– Leo – 2017-11-03T01:05:09.700

@Leo Oops. Should I delete the post since it's not valid? I guess you're a super robber. Not sure how I missed that, I remember trying those cases – dylnan – 2017-11-03T14:55:01.767

I'd say don't delete it: you're "cracked" anyways and the robber deserves credit :) – Felix Palmen – 2017-11-03T17:30:20.193

3

6502 machine code (C64), LD = 1 (cracked)

00 C0 20 FD AE A0 00 99 5B 00 C8 20 73 00 90 F7 99 5B 00 A2 0B CA 88 30 09 B9
5B 00 29 0F 95 5B 10 F3 A9 00 95 5B CA 10 F9 A9 00 A0 03 99 69 00 88 10 FA A0
20 A2 76 18 B5 E6 90 02 09 10 4A 95 E6 E8 10 F4 A2 03 76 69 CA 10 FB 88 F0 11
A2 09 B5 5C C9 08 30 04 E9 03 95 5C CA 10 F3 30 D6 A2 03 B5 69 95 57 CA 10 F9
A9 01 85 FB A2 03 A9 00 95 FB CA D0 FB A2 03 B5 FB 95 22 95 26 CA 10 F7 A9 00
A2 03 95 69 CA 10 FB A0 20 A2 02 46 25 76 22 CA 10 FB 90 0C A2 7C 18 B5 AA 75
ED 95 ED E8 10 F7 A2 7D 06 26 36 AA E8 10 FB 88 10 DD A0 0B A9 00 99 5A 00 88
D0 FA A0 20 A2 09 B5 5C C9 05 30 04 69 02 95 5C CA 10 F3 06 69 A2 FD 36 6D E8
D0 FB A2 09 B5 5C 2A C9 10 29 0F 95 5C CA 10 F4 88 D0 D7 E0 0A F0 05 E8 B5 5B
F0 F7 09 30 99 5B 00 C8 E8 E0 0B F0 04 B5 5B 90 F1 88 B9 5B 00 C9 30 F0 F8 A2
7C 18 B5 DB E9 00 95 DB E8 10 F7 90 14 88 30 05 B9 5B 00 D0 EA A2 7C F6 7F D0
03 E8 10 F9 4C 73 C0 B9 5B 00 4C D2 FF

Online demo, usage: sys49152,n where n is the 0-indexed input.


For the last test case, you need a bit of patience, as this poor machine has to do millions of bit-shifts and additions to present you the result ;)

The language here is the machine code, so LD is measured in this format -- nevertheless, to give something to start with, here's the program in ca65 assembler source:

NUMSIZE         = 4     ; 32 bit integers ...
NUMSTRSIZE      = 11    ; need up to 11 characters for 0-terminated string

.segment "ZPUSR": zeropage
v_x:            .res    NUMSIZE         ; next number to be squared

.segment "ZPFAC": zeropage
v_n:            .res    NUMSIZE         ; input index (0-based), counts down
nc_string:      .res    NUMSTRSIZE      ; string buffer for numbers

.segment "ZPTMP": zeropage
mpm_arg1:       .res    NUMSIZE         ; arg1 for multiplication
mpm_arg2:       .res    NUMSIZE         ; arg2 for multiplication

.segment "ZPFAC2": zeropage
mpm_res:        .res    NUMSIZE         ; numeric result (mult and str convert)

; load address for creating a C64 .PRG file:

.segment "LDADDR"
                .word   $c000

.code

; first read number from command argument and convert to unsigned
; integer in little-endian:

                jsr     $aefd
                ldy     #$00
rn_loop:        sta     nc_string,y
                iny
                jsr     $73
                bcc     rn_loop
                sta     nc_string,y
                ldx     #NUMSTRSIZE
stn_copybcd:    dex
                dey
                bmi     stn_fillzero
                lda     nc_string,y
                and     #$f
                sta     nc_string,x
                bpl     stn_copybcd
stn_fillzero:   lda     #$0
                sta     nc_string,x
                dex
                bpl     stn_fillzero
                lda     #$0
                ldy     #(NUMSIZE-1)
stn_znumloop:   sta     mpm_res,y
                dey
                bpl     stn_znumloop
                ldy     #(NUMSIZE*8)
stn_loop:       ldx     #($81-NUMSTRSIZE)
                clc
stn_rorloop:    lda     nc_string+NUMSTRSIZE+$80,x
                bcc     stn_skipbit
                ora     #$10
stn_skipbit:    lsr     a
                sta     nc_string+NUMSTRSIZE+$80,x
                inx
                bpl     stn_rorloop
                ldx     #(NUMSIZE-1)
stn_ror:        ror     mpm_res,x
                dex
                bpl     stn_ror
                dey
                beq     main
stn_sub:        ldx     #(NUMSTRSIZE-2)
stn_subloop:    lda     nc_string+1,x
                cmp     #$8
                bmi     stn_nosub
                sbc     #$3
                sta     nc_string+1,x
stn_nosub:      dex
                bpl     stn_subloop
                bmi     stn_loop

main:
                ldx     #(NUMSIZE-1)
argloop:        lda     mpm_res,x
                sta     v_n,x
                dex
                bpl     argloop
                lda     #$01
                sta     v_x
                ldx     #(NUMSIZE-1)
                lda     #$00
initxloop:      sta     v_x,x
                dex
                bne     initxloop

mainloop:

; prepare arguments for multiplication:

                ldx     #(NUMSIZE-1)
sqrargloop:     lda     v_x,x
                sta     mpm_arg1,x
                sta     mpm_arg2,x
                dex
                bpl     sqrargloop

; do multiplication:

                lda     #$00
                ldx     #(NUMSIZE-1)
mul_clearloop:  sta     mpm_res,x
                dex
                bpl     mul_clearloop
                ldy     #(NUMSIZE*8)
mul_loop:       ldx     #(NUMSIZE-2)
                lsr     mpm_arg1+NUMSIZE-1
mul_rorloop:    ror     mpm_arg1,x
                dex
                bpl     mul_rorloop
                bcc     mul_noadd
                ldx     #($80-NUMSIZE)
                clc
mul_addloop:    lda     mpm_arg2+NUMSIZE+$80,x
                adc     mpm_res+NUMSIZE+$80,x
                sta     mpm_res+NUMSIZE+$80,x
                inx
                bpl     mul_addloop
mul_noadd:      ldx     #($81-NUMSIZE)
                asl     mpm_arg2
mul_rolloop:    rol     mpm_arg2+NUMSIZE+$80,x
                inx
                bpl     mul_rolloop
                dey
                bpl     mul_loop

; convert result to string:

                ldy     #NUMSTRSIZE
                lda     #$0
nts_fillzero:   sta     nc_string-1,y
                dey
                bne     nts_fillzero
                ldy     #(NUMSIZE*8)
nts_bcdloop:    ldx     #(NUMSTRSIZE-2)
nts_addloop:    lda     nc_string+1,x
                cmp     #$5
                bmi     nts_noadd
                adc     #$2
                sta     nc_string+1,x
nts_noadd:      dex
                bpl     nts_addloop
                asl     mpm_res
                ldx     #($ff-NUMSIZE+2)
nts_rol:        rol     mpm_res+NUMSIZE,x       ; + $100 w/o zp wraparound
                inx
                bne     nts_rol
                ldx     #(NUMSTRSIZE-2)
nts_rolloop:    lda     nc_string+1,x
                rol     a
                cmp     #$10
                and     #$f
                sta     nc_string+1,x
nts_rolnext:    dex
                bpl     nts_rolloop
                dey
                bne     nts_bcdloop
nts_scan:       cpx     #(NUMSTRSIZE-1)
                beq     nts_copydigits
                inx
                lda     nc_string,x
                beq     nts_scan
nts_copydigits: ora     #$30
                sta     nc_string,y
                iny
                inx
                cpx     #(NUMSTRSIZE)
                beq     strip0loop
                lda     nc_string,x
                bcc     nts_copydigits

; search for first non-0 character from the end of the string:

strip0loop:     dey
                lda     nc_string,y
                cmp     #$30
                beq     strip0loop

; decrement n for each digit:

founddigit:
                ldx     #($80-NUMSIZE)
                clc
decnloop:       lda     v_n+NUMSIZE+$80,x
                sbc     #$00
                sta     v_n+NUMSIZE+$80,x
                inx
                bpl     decnloop
                bcc     foundresult

                dey
                bmi     next_x
                lda     nc_string,y
                bne     founddigit

; increment x to calculate next square number:

next_x:
                ldx     #($80-NUMSIZE)
incxloop:       inc     v_x+NUMSIZE-$80,x
                bne     incxdone
                inx
                bpl     incxloop
incxdone:       jmp     mainloop

foundresult:    lda     nc_string,y
                jmp     $ffd2

... and here's the linker script for ld65:

MEMORY {
  LDADDR: start = $bffe, size = 2;
  CODE: start = $c000, size = $1000;
  ZPTMP: start = $0022, size = $0008;
  ZPFAC: start = $0057, size = $000f;
  ZPFAC2: start = $0069, size = $0004;
  ZPUSR: start = $00fb, size = $0004;
}

SEGMENTS {
  LDADDR: load = LDADDR;
  CODE: load = CODE;
  ZPTMP: load = ZPTMP, type = zp;
  ZPFAC: load = ZPFAC, type = zp;
  ZPFAC2: load = ZPFAC2, type = zp;
  ZPUSR: load = ZPUSR, type = zp;
}

Felix Palmen

Posted 2017-11-02T14:03:23.480

Reputation: 3 866

cracked (I believe) – Jo. – 2017-11-10T06:38:17.683

@Jo. yes, edited. – Felix Palmen – 2017-11-10T09:25:55.237

2

Perl 5, 59 + 1 (-a) = 60 bytes, LD=55

$j.=int reverse$_**2for 1..$_;$_--;say$j=~s/.{$_}(.).*/$1/r

Try it online!

Xcali

Posted 2017-11-02T14:03:23.480

Reputation: 7 671

maybe cracked, I'm not sure of my entry https://codegolf.stackexchange.com/questions/146927/levenshtein-distance-oeis-robbers/147045#147045

– Nahuel Fouilleul – 2017-11-03T13:01:09.027

2

Java 8, (177 bytes) LD = 92 (Cracked by @Arnauld)

(Ive used this online LD-calculator.)

n->{String r="",t=r;for(int i=1,j;r.length()<=n+1;i++)if(Math.sqrt(i)%1==0){for(t="",j=(i+"").length();j>0;t+=(i+"").charAt(--j));r+=t.replaceAll("^0+","");}return r.charAt(n);}

This is probably not too hard if you simply golf this. :)

Explanation:

Try it here.

n->{                             // Method with integer parameter and character return-type
  String r="",                   //  Result-String, starting empty
         t=r;                    //  Temp-String, starting empty
  for(int i=1,j;                 //  Index-integers
      r.length()<=n+1;i++)       //  Loop (1) as long as the length is at least n+1
    if(Math.sqrt(i)%1==0){       //   If the current number `i` is a perfect square:
      for(t="",                  //    Reset the temp-String to empty
          j=(i+"").length();     //    Set `j` to the length of the current number
          j>0;                   //    Inner loop (2) as long as `j` is larger than 0
        t+=                      //     Append the temp-String with:
           (i+"").charAt(--j)    //     The digit of integer `i` at index `j-1`
                                 //     (by first decrease `j` with 1 with `--j`)
      );                         //    End of inner loop (2)
      r+=t                       //    And then append the temp-String to the result-String
          .replaceAll("^0+","");}//    after we've removed any leading zeroes
                                 //  End of loop (1) (implicit / single-line body)
  return r.charAt(n);            //  Return the `n`'th character of the result-String
}                                // End of method

Kevin Cruijssen

Posted 2017-11-02T14:03:23.480

Reputation: 67 575

1Cracked – Arnauld – 2017-11-03T23:09:00.633

Intended solution: n->{String r="";for(int i=1;r.length()<=n+1;r+=new Long(new StringBuffer(i*i+++"").reverse()+""));return r.charAt(n);} (118 bytes, 92 LD) – Kevin Cruijssen – 2017-11-04T11:13:03.993

2

Octave, LD = 63, Cracked

@(t)[arrayfun(@(t)num2str(str2num(flip(num2str(t)))),(1:t).^2,'uni',0){:}](t)

Try it online!

The submission is 77 bytes, so you need to substitute quite a bit =)

Stewie Griffin

Posted 2017-11-02T14:03:23.480

Reputation: 43 471

cracked. – Tom Carpenter – 2017-11-04T17:38:17.687

2

6502 machine code (C64), LD = 1, safe

00 C0 20 FD AE A0 00 99 5B 00 C8 20 73 00 90 F7 99 5B 00 A2 0B CA 98 88 30 09
B9 5B 00 29 0F 95 5B 10 F2 95 5B CA 10 FB A0 20 A2 76 18 B5 E6 90 02 09 10 4A
95 E6 E8 10 F4 A2 03 76 69 CA 10 FB 88 F0 11 A2 09 B5 5C C9 08 30 04 E9 03 95
5C CA 10 F3 30 D6 A2 03 B5 69 95 57 CA 10 F9 A9 01 85 FB A2 03 A9 00 95 FB CA
D0 FB A2 03 B5 FB 95 22 95 26 CA 10 F7 A9 00 A2 03 95 69 CA 10 FB A0 20 A2 02
46 25 76 22 CA 10 FB 90 0C A2 7C 18 B5 AA 75 ED 95 ED E8 10 F7 A2 7D 06 26 36
AA E8 10 FB 88 10 DD A2 0B A9 00 95 5A CA D0 FB A0 20 A2 09 B5 5C C9 05 30 04
69 02 95 5C CA 10 F3 06 69 A2 FD 36 6D E8 D0 FB A2 09 B5 5C 2A C9 10 29 0F 95
5C CA 10 F4 88 D0 D7 E8 B5 5B F0 FB 09 30 99 5B 00 C8 E8 E0 0B F0 04 B5 5B 90
F1 88 B9 5B 00 C9 30 F0 F8 A2 7C 18 B5 DB E9 00 95 DB E8 10 F7 90 14 88 30 05
B9 5B 00 D0 EA A2 7C F6 7F D0 03 E8 10 F9 4C 68 C0 B9 5B 00 4C D2 FF

Online demo, usage: sys49152,n where n is the 0-indexed input.


Intended solution: (diff)

 B9 5B 00 29 0F 95 5B 10 F2 95 5B CA 10 FB A0 20 A2 76 18 B5 E6 90 02 09 10 4A
-95 E6 E8 10 F4 A2 03 76 69 CA 10 FB 88 F0 11 A2 09 B5 5C C9 08 30 04 E9 03 95
+95 E6 E8 10 F4 A2 03 76 69 CA 10 FB 88 F0 11 A2 09 B5 5C C9 08 90 04 E9 03 95
 5C CA 10 F3 30 D6 A2 03 B5 69 95 57 CA 10 F9 A9 01 85 FB A2 03 A9 00 95 FB CA

The 30 (opcode bmi) is replaced by 90 (opcode bcc). This corresponds to the following part in the assembler source:

stn_subloop:    lda     nc_string+1,x
                cmp     #$8
                bmi     stn_nosub       ; use bcc here for same result
                sbc     #$3
                sta     nc_string+1,x

It works because this code checks whether a number is smaller than 8. The cmp instruction performs a subtraction for that, setting the flags accordingly. So, if the accumulator holds a number smaller than 8, this underflows, clearing the carry flag, therefore the correct branch instruction is indeed bcc. bmi (branching when negative), as in the original code, just happens to work here as well, because the compared numbers are small enough, so the result of the subtraction ends up in the negative range ($80-$ff) when an underflow occurs.

Online demo


This is an improved/compacted version of my previous submission. Among some other tricks to reduce the size, it removes the useless code that was contained and allowed a kind of "simple"*) crack. All in all, the size is reduced by 16 bytes. This time, it should be a bit harder to find the equivalent program with LD 1 :)

*) probably still quite some work to find, of course :)

Again, here's the ca65 assembler source, to help getting started with the code:

NUMSIZE         = 4     ; 32 bit integers ...
NUMSTRSIZE      = 11    ; need up to 11 characters for 0-terminated string

.segment "ZPUSR": zeropage
v_x:            .res    NUMSIZE         ; next number to be squared

.segment "ZPFAC": zeropage
v_n:            .res    NUMSIZE         ; input index (0-based), counts down
nc_string:      .res    NUMSTRSIZE      ; string buffer for numbers

.segment "ZPTMP": zeropage
mpm_arg1:       .res    NUMSIZE         ; arg1 for multiplication
mpm_arg2:       .res    NUMSIZE         ; arg2 for multiplication

.segment "ZPFAC2": zeropage
mpm_res:        .res    NUMSIZE         ; numeric result (mult and str convert)

; load address for creating a C64 .PRG file:

.segment "LDADDR"
                .word   $c000

.code

; first read number from command argument and convert to unsigned
; integer in little-endian:

                jsr     $aefd
                ldy     #$00
rn_loop:        sta     nc_string,y
                iny
                jsr     $73
                bcc     rn_loop
                sta     nc_string,y
                ldx     #NUMSTRSIZE
stn_copybcd:    dex
                tya
                dey
                bmi     stn_fillzero
                lda     nc_string,y
                and     #$f
                sta     nc_string,x
                bpl     stn_copybcd
stn_fillzero:   sta     nc_string,x
                dex
                bpl     stn_fillzero
                ldy     #(NUMSIZE*8)
stn_loop:       ldx     #($81-NUMSTRSIZE)
                clc
stn_rorloop:    lda     nc_string+NUMSTRSIZE+$80,x
                bcc     stn_skipbit
                ora     #$10
stn_skipbit:    lsr     a
                sta     nc_string+NUMSTRSIZE+$80,x
                inx
                bpl     stn_rorloop
                ldx     #(NUMSIZE-1)
stn_ror:        ror     mpm_res,x
                dex
                bpl     stn_ror
                dey
                beq     main
stn_sub:        ldx     #(NUMSTRSIZE-2)
stn_subloop:    lda     nc_string+1,x
                cmp     #$8
                bmi     stn_nosub
                sbc     #$3
                sta     nc_string+1,x
stn_nosub:      dex
                bpl     stn_subloop
                bmi     stn_loop

main:
                ldx     #(NUMSIZE-1)
argloop:        lda     mpm_res,x
                sta     v_n,x
                dex
                bpl     argloop
                lda     #$01
                sta     v_x
                ldx     #(NUMSIZE-1)
                lda     #$00
initxloop:      sta     v_x,x
                dex
                bne     initxloop

mainloop:

; prepare arguments for multiplication:

                ldx     #(NUMSIZE-1)
sqrargloop:     lda     v_x,x
                sta     mpm_arg1,x
                sta     mpm_arg2,x
                dex
                bpl     sqrargloop

; do multiplication:

                lda     #$00
                ldx     #(NUMSIZE-1)
mul_clearloop:  sta     mpm_res,x
                dex
                bpl     mul_clearloop
                ldy     #(NUMSIZE*8)
mul_loop:       ldx     #(NUMSIZE-2)
                lsr     mpm_arg1+NUMSIZE-1
mul_rorloop:    ror     mpm_arg1,x
                dex
                bpl     mul_rorloop
                bcc     mul_noadd
                ldx     #($80-NUMSIZE)
                clc
mul_addloop:    lda     mpm_arg2+NUMSIZE+$80,x
                adc     mpm_res+NUMSIZE+$80,x
                sta     mpm_res+NUMSIZE+$80,x
                inx
                bpl     mul_addloop
mul_noadd:      ldx     #($81-NUMSIZE)
                asl     mpm_arg2
mul_rolloop:    rol     mpm_arg2+NUMSIZE+$80,x
                inx
                bpl     mul_rolloop
                dey
                bpl     mul_loop

; convert result to string:

                ldx     #NUMSTRSIZE
                lda     #$0
nts_fillzero:   sta     nc_string-1,x
                dex
                bne     nts_fillzero
                ldy     #(NUMSIZE*8)
nts_bcdloop:    ldx     #(NUMSTRSIZE-2)
nts_addloop:    lda     nc_string+1,x
                cmp     #$5
                bmi     nts_noadd
                adc     #$2
                sta     nc_string+1,x
nts_noadd:      dex
                bpl     nts_addloop
                asl     mpm_res
                ldx     #($ff-NUMSIZE+2)
nts_rol:        rol     mpm_res+NUMSIZE,x       ; + $100 w/o zp wraparound
                inx
                bne     nts_rol
                ldx     #(NUMSTRSIZE-2)
nts_rolloop:    lda     nc_string+1,x
                rol     a
                cmp     #$10
                and     #$f
                sta     nc_string+1,x
nts_rolnext:    dex
                bpl     nts_rolloop
                dey
                bne     nts_bcdloop
nts_scan:       inx
                lda     nc_string,x
                beq     nts_scan
nts_copydigits: ora     #$30
                sta     nc_string,y
                iny
                inx
                cpx     #(NUMSTRSIZE)
                beq     strip0loop
                lda     nc_string,x
                bcc     nts_copydigits

; search for first non-0 character from the end of the string:

strip0loop:     dey
                lda     nc_string,y
                cmp     #$30
                beq     strip0loop

; decrement n for each digit:

founddigit:
                ldx     #($80-NUMSIZE)
                clc
decnloop:       lda     v_n+NUMSIZE+$80,x
                sbc     #$00
                sta     v_n+NUMSIZE+$80,x
                inx
                bpl     decnloop
                bcc     foundresult

                dey
                bmi     next_x
                lda     nc_string,y
                bne     founddigit

; increment x to calculate next square number:

next_x:
                ldx     #($80-NUMSIZE)
incxloop:       inc     v_x+NUMSIZE-$80,x
                bne     incxdone
                inx
                bpl     incxloop
incxdone:       jmp     mainloop

foundresult:    lda     nc_string,y
                jmp     $ffd2

... and here's the linker script for ld65:

MEMORY {
  LDADDR: start = $bffe, size = 2;
  CODE: start = $c000, size = $1000;
  ZPTMP: start = $0022, size = $0008;
  ZPFAC: start = $0057, size = $000f;
  ZPFAC2: start = $0069, size = $0004;
  ZPUSR: start = $00fb, size = $0004;
}

SEGMENTS {
  LDADDR: load = LDADDR;
  CODE: load = CODE;
  ZPTMP: load = ZPTMP, type = zp;
  ZPFAC: load = ZPFAC, type = zp;
  ZPFAC2: load = ZPFAC2, type = zp;
  ZPUSR: load = ZPUSR, type = zp;
}

Felix Palmen

Posted 2017-11-02T14:03:23.480

Reputation: 3 866

Consider it un-cracked :) – Jo. – 2017-11-16T02:24:17.047

@Jo. well if you insist -- thanks a lot, I edited it. – Felix Palmen – 2017-11-17T09:18:47.453

1

Lua : LD=1, cracked

i=1s=""while(#s<...+0)do s=s..((i*i)..""):reverse():gsub("(0+)(%d+)$","%2")i=i+1 end print(s:sub(...,...))

No fancy tricks here :)

Katenkyo

Posted 2017-11-02T14:03:23.480

Reputation: 2 857

cracked – Erik the Outgolfer – 2017-11-02T14:31:20.317

1

Mathematica, LD=43 cracked

Flatten[Table[(k=IntegerDigits)@FromDigits@Reverse@k[i^2],{i,10^4}]][[#]]&

Try it online!

J42161217

Posted 2017-11-02T14:03:23.480

Reputation: 15 931

Cracked. – Misha Lavrov – 2017-11-02T18:24:08.613

1

PHP, LD = 35 (Cracked)

1-indexed

<?while(strlen($s)<$argv[1])$s.=(int)strrev(++$i*$i);echo substr($s,$argv[1]-1,1);

Try it online!

Jo.

Posted 2017-11-02T14:03:23.480

Reputation: 974

0

Python 3: LD = 9 | Cracked

lambda i:"".join(str(k*k+2*k+1)[::-1].lstrip("0")for k in range(i+1))[i]

This one should be fairly (very) easy to get :P

HyperNeutrino

Posted 2017-11-02T14:03:23.480

Reputation: 26 575

Cracked. – Mr. Xcoder – 2017-11-02T14:18:58.503

1I deleted my Crack because the original answer is invalid. – Mr. Xcoder – 2017-11-02T16:32:49.670

@Mr.Xcoder You can undelete now; LD is the same because the .lstrip("0") part can just be copied over. – HyperNeutrino – 2017-11-02T17:10:55.333

Done – Mr. Xcoder – 2017-11-02T17:12:51.177

0

Groovy, 61 bytes (LD = 23)

{(1..it).collect{0.valueOf("${it**2}".reverse())}.join()[it]}

Try it online!

Magic Octopus Urn

Posted 2017-11-02T14:03:23.480

Reputation: 19 422

How is this safe >_>... – Magic Octopus Urn – 2017-11-17T15:40:00.953

0

C++, LD = 159

0-indexed, input in argv[1], compiled on GCC 7.2.0

#import<bits/stdc++.h>
char*h,b[1<<17],*q=b;int x,y;main(int,char**j){sscanf(j[1],"%d",&y);do{x++;q+=sprintf(h=q,"%d",x*x);while(*--q==48);std::reverse(h,++q);}while(q-b<=y);b[y+1]=0,printf(b+y);}

Colera Su

Posted 2017-11-02T14:03:23.480

Reputation: 2 291