13
\$\begingroup\$

This challenge is created in celebration of my first esoteric language, Backhand!

Backhand is a one dimensional language with a non-linear pointer flow. The pointer moves three steps at a time, only executing every third instruction.

The program 1..1..+..O..@ will add 1+1 and output 2 before terminating. The intermediate instructions are skipped, so 1<>1()+{}O[]@ is exactly the same program.

When the pointer is about to step off the end of the tape, it instead reverses direction and steps the other way, so 1.@1.O+. is the same program. Note that it only counts the end instruction once. This allows us to compress most linear programs down, such as 1O+1@

Your challenge here is to write a program or function that take a string, and output the instructions that would be executed if the program was interpreted like Backhand (you don't need to handle any actual Backhand instructions). You are to only output until the pointer lands on the last character of the string (at which point the execution would normally go backwards).

But wait, that's not all! When your program itself is interpreted in this fashion, the resulting code should output one of the below:

  • (Mostly) works
  • Turing complete
  • 'Recreational' (quotes can be either ' or ", but not both)
  • Perfectly okay
  • Only a few bugs

For example, if your source code is code 2 backhand, then the program ce cankb od2ahd should output one of these phrases.

Test cases:

"1  1  +  O  @"  -> "11+O@"
"1O+1@"          -> "11+O@"
"HoreWll dlo!"   -> "Hello World!"
"abcdefghijklmnopqrstuvwxyz" -> "adgjmpsvyxurolifcbehknqtwz"
"0123456789"     -> "0369"  (not "0369630369")
"@"              -> "@"
"io"             -> "io"  (Cat program in Backhand)
"!?O"            -> "!?O" (Outputs random bits forever in Backhand)
"---!---!"       -> "-!-----!"

And a reference program written in, of course, Backhand (this might be a bit buggy Okay, I think I've fixed it).

Rules.

  • Standard Loopholes are forbidden
  • The input of the first program will contain only printable ASCII and newlines (that is, bytes 0x20-0x7E as well as 0x0A)
  • You can choose whether your second program is converted from your first by bytes or by UTF-8 characters.
  • Second program:
    • Case does not matter, so your output could be pErFectLy OKay if you want.
    • Any amount of trailing/leading whitespace (newline, tabs, spaces) are also okay.
    • The second program should be the same language as the first, though not necessarily the same format (program/function)
    • I'm happy to include suggestions from the comments on extra phrases (as long as they're not too short)
  • As this is , your aim is to get the shortest answer for your language!
  • In two weeks, I'll award a 200 bounty to the shortest Backhand answer.
\$\endgroup\$
  • \$\begingroup\$ Sandbox (deleted) \$\endgroup\$ – Jo King Oct 2 '18 at 14:13
  • 1
    \$\begingroup\$ Suggested testcase: "---!---!" (or any string where the last character appears more than once) \$\endgroup\$ – TFeld Oct 2 '18 at 14:27
  • \$\begingroup\$ When your program itself is interpreted in this fashion - interpreted by what? \$\endgroup\$ – ngm Oct 2 '18 at 15:08
  • 4
    \$\begingroup\$ So let's say I write an R program (because that's pretty much all I do around here.) My R program has to transform the Backhanded code into the sequence of Backhanded instructions. In addition, my R program when input into into itself has to become another R program that outputs on of those strings when run (in the case of R, interpreted by an R interpreter). Is this correct? \$\endgroup\$ – ngm Oct 2 '18 at 15:36
  • 1
    \$\begingroup\$ @ngm Yes. ----- \$\endgroup\$ – user202729 Oct 2 '18 at 16:16
4
\$\begingroup\$

R, 187 bytes

 # c  a  t  (  '  P  e  r  f  e  c  t  l  y     o  k  a  y  '  )  #
g=function(x,n=nchar(x),i=c(1:n,(n-1):1,2:n),j=seq(1,3*n-2,3),k=i[j][1:which(i[j]==n)[1]])cat(substring(x,k,k),sep='') 

Try it online!

The single space at the end is needed so that the \n never gets printed when the program is applied to itself.

Explanation

Part 1:

Ungolfed:

 # c  a  t  (  '  P  e  r  f  e  c  t  l  y     o  k  a  y  '  )  #
g <- function(x) {
  n <- nchar(x)                      # number of characters in string
  i <- c(1:n, (n - 1):1, 2:n)        # index: 1 to n, n-1 back to 1, 2 to n
  j <- seq(1, 3 * n - 2, 3)          # every third element of i
  k <- i[j][1:which(i[j] == n)[1]]   # the elements of i at indices j, up to the first appearance of n
  cat(substring(x, k, k), sep = "")  # extract from x the characters at indices k, and paste them together
}

Part 2:

The function produces this when it acts on the entire program:

cat('Perfectly okay')#=ni(ncr)=1,-:2)=q,n,,i]:i(j=[]assi(k)e' 
\$\endgroup\$
4
\$\begingroup\$

Python 2, 163 130 127 121 115 99 96 bytes

i=input() ###
print(i+i[-2:0:-1]+i)[:len(i)*(len(i)%3%2or 3):3]  

#'p lr+yi  n'ottk(ca'eyPf'er)

Try it online!

Outputs:

int #rt+-01i:n)l(%2 : 
print('Perfect' + # 33o3ie*(l)]:2i(i
#(p=iu)#pni[:-+[ei(n)%r)]
'ly okay')
\$\endgroup\$
3
\$\begingroup\$

Perl 6, 101 86 bytes

Wow, -25 bytes thanks to nwellnhof by drastically improving the first program

##
{S:g/(.).?.?/$0/}o{.comb%3-1??.chop~.flip~S/.//!!$_} #
#}{ "" s( kM ro os wt  l )y.

Try it online!

I'm hoping more people take advantage of the rebound like this. The Backhanded program is

#{g.?//{o%1.o.iS/!}
{"(Mostly) works"}#_!.~l~h?-bco0?.(:
#S/).$}.m3?cpfp//$ #        .

Which comments out to just {"(Mostly) works"}.

\$\endgroup\$
3
\$\begingroup\$

05AB1E, 43 40 38 37 bytes

-2 bytes (40→38) thanks to @Emigna.

„€€Ã€„Ѐ€µ'€Ý)\[ûDN3*©è  ?®IgD#<ÖNĀ*#

Try it online. (PS: Switch the language from 05AB1E (legacy) to 05AB1E for test case 0123456789. The legacy version is faster, but it shows incorrect results for number inputs with leading zeros.)

The 'backhanded' program will become:

„ÃеÝ[N© I#N#

Which will output perfectly okay in full lowercase.

Try it online.

Explanation base program:

„€€Ã€           # Push the string "the pointed"
„Ѐ€µ           # Push the string "dm one"
'€Ý            '# Push the string "been"
     )          # Wrap the entire stack in a list
      \         # And remove that list from the stack again
[               # Start an infinite loop
 û              #  Palindromize the string at the top of the stack
                #   i.e. "1O+1@" becomes "1O+1@1+O1" the first iteration,
                #        and "1O+1@1+O1O+1@1+O1" the next iteration, etc.
  D             #  Duplicate the palindromized string
 N3*            #  0-indexed index of the loop multiplied by 3
    ©           #  Save it in the register (without popping)
     è?         #  Index into the string and print the character
  Ig            #  If the length of the input is exactly 1:
     #          #   Stop the infinite loop
 ®  D <Ö        #  If the value from the register is divisible by the length - 1
          *     #  And
        NĀ      #  The 0-indexed index of the loop is NOT 0:
           #    #   Stop the infinite loop

Explanation 'backhanded' program:

„ÃÐµÝ           # Push the string "perfectly okay"
     [          # Start an infinite loop
      N©        #  Push the index, and store it in the register (without popping)
          I     #  Push the input (none given, so nothing happens)
           #    #  If the top of the stack is 1, stop the infinite loop
            N   #  Push the index again
             #  #  If the top of the stack is 1, stop the infinite loop

Step by step the following happens:

  1. „ÃеÝ: STACK becomes ["perfectly okay"]
  2. [: Start infinite loop
  3. (first loop iteration) : STACK becomes ["perfectly okay", 0]
  4. (first loop iteration) I: STACK remains ["perfectly okay", 0] because there is no input
  5. (first loop iteration) #: STACK becomes ["perfectly okay"], and the loop continues
  6. (first loop iteration) N: STACK becomes ["perfectly okay", 0]
  7. (first loop iteration) #: STACK becomes ["perfectly okay"], and the loop continues
  8. (second loop iteration) : STACK becomes ["perfectly okay", 1]
  9. (second loop iteration) I: STACK remains ["perfectly okay", 1] because there is no input
  10. (second loop iteration) #: STACK becomes ["perfectly okay"], and the loop breaks because of the 1 (truthy)
  11. Implicitly prints the top of the stack to STDOUT: perfectly okay

See the steps here with the debugger on TIO enabled.

See this 05AB1E tip of mine (section How to use the dictionary?) to understand why „€€Ã€„Ѐ€µ'€Ý are the pointed, dm one, and been and „ÃÐµÝ is perfectly okay.


Old 38-byte version:

„€€Ã€„Ѐ€µ'€Ý)\ giqë¬?[ûDN>3*©è?®Ig<Ö#

Try it online. (PS: Switch the language from 05AB1E (legacy) to 05AB1E for test cases 0123456789 and @. The legacy version is faster, but it shows incorrect results for number inputs with leading zeros or single-char inputs.)

The 'backhanded' program will become:

„ÃÐµÝ q?D3èIÖ<®©>û¬i\€€„€€€€')gë[N*?g#

(Where the q exits the program and makes everything else no-ops.)

Try it online.

\$\endgroup\$
  • \$\begingroup\$ Surely / should be `\`? \$\endgroup\$ – Emigna Oct 3 '18 at 10:24
  • 1
    \$\begingroup\$ Using N>3*© instead of XU saves 2. I also feel like there should be some way do all printing in the loop, which would save even more bytes. \$\endgroup\$ – Emigna Oct 3 '18 at 11:24
  • \$\begingroup\$ @Emigna Yeah, / should have been \ .. And thanks for the -2. I indeed have the feeling it can be golfed further. It seems overly long for the base functionality of printing every 3rd value including bouncing back. \$\endgroup\$ – Kevin Cruijssen Oct 3 '18 at 11:44
  • \$\begingroup\$ @Emigna Very ugly, but [ûDN3*©è?®IgD#<ÖNĀ*# is without the if-else beforehand, which is 2 bytes shorter than the if-else with loop. Unfortunately, we still need the q for the backhanded program, so it will be also 38 bytes. But I have the feeling that break can definitely be improved somehow keeping in mind single-char inputs, index 0, and divisibility by length-1 at the same time.. \$\endgroup\$ – Kevin Cruijssen Oct 3 '18 at 12:10
2
\$\begingroup\$

Python 2, 130 bytes

p='r'#i  n  t  '  P  e  r  f  e  c  t  l  y     o  k  a  y  '  # 
s=input();S=s+s[-2:0:-1]+s
print S[:len(~-len(s)%3and S or s):3]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 130 bytes

Early attempt. Not very satisfying.

f  =/*>  "  P  e  r  f  e  c  t  l  y     o  k  a*/y=>""+/**/(g=p=>(c=y[p])?m++%3?g(p+d):y[p+1]?c+g(p+d):c:g(p-d-d,d=-d))(m=0,d=1)

Try it online!

When the code is processed by itself, the following characters are isolated:

f  =/*>  "  P  e  r  f  e  c  t  l  y     o  k  a*/y=>""+/**/…
^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^  ^

which gives:

f=>"Perfectly okay"//…
\$\endgroup\$
1
\$\begingroup\$

Jelly, 34 bytes

JŒḄȧ`ȯ“”NNŒḄ2¡3s@”]ȧZỴḢḢ»`Qị⁸ȧ@11€

A full program or monadic link accepting a list of characters which prints or yields (respectively).

Try it online! Or see the test-suite.

The Backhand-parsed code is then:

Jȧ“N2s]Ỵ»ị@€

A full program or niladic link printing or yielding (respectively) Turing complete.

How?

JŒḄȧ`ȯ“”NNŒḄ2¡3s@”]ȧZỴḢḢ»`Qị⁸ȧ@11€ - Main Link: list of characters   e.g. 'abcd'
J                                  - range of length                      [1,2,3,4]
 ŒḄ                                - bounce                         [1,2,3,4,3,2,1]
    `                              - use as both arguments of:
   ȧ                               -   logical AND [x AND x = x]
      “”                           - literal empty list of characters
     ȯ                             - logical OR [when x is truthy: x OR y = x]
        N                          - negate  }
         N                         - negate  } together a no-op
             ¡                     - repeat this...
            2                      - ... two times:
          ŒḄ                       -   bounce                       [1,2,3,4,3,2,1,2,3,4,3,2,1,2,3,4,3,2,1,2,3,4,3,2,1]
              3                    - literal three
               s@                  - split into (threes)            [[1,2,3],[4,3,2],[1,2,3],[4,3,2],[1,2,3],[4,3,2],[1,2,3],[4,3,2],[1]]
                 ”]                - literal ']' character
                   ȧ               - logical AND [']' is truthy so a no-op]
                    Z              - transpose                      [[1,4,1,4,1,4,1,4,1],[2,3,2,3,2,3,2,3],[3,2,3,2,3,2,3,2]]
                     Ỵ             - split at new lines [no newline characters exist in this list of ints so effectively wrap in a list]
                      Ḣ            - head [undo that wrap]
                       Ḣ           - head [get the first of the transposed split indices]
                                   -                                [1,4,1,4,1,4,1,4,1]
                         `         - use as both arguments of:
                        »          -   maximum [max(x, x) = x]
                          Q        - de-duplicate                   [1,4]
                            ⁸      - chain's left argument (the input)
                           ị       - index into it                  "ad"
                               11€ - literal eleven for €ach (of input)
                             ȧ@    - logical AND with swapped args [[11,11,...,11] is truthy]
                                   -                                "ad"
                                   - (as a full program implicit print)

the Backhand-parsed code is then:

Jȧ“N2s]Ỵ»ị@€ - Main Link: no arguments
J            - range of length (of an implicit 0, treated as [0]) -> [1]
  “N2s]Ỵ»    - compression of "Turing complete"
 ȧ           - logical AND [[1] is truthy] -> "Turing complete"
           € - for each character in the list of characters:
          @  -   with swapped arguments (an implicit 0 is on the right, so f(0, "Turing complete"))
         ị   -     index into
             - (as a full program implicit print)
\$\endgroup\$
1
\$\begingroup\$

Runic Enchantments, 294 bytes

>; "  O  n  l  y     a     F  e  w     B  u  g  s  "  @
                                  /{\!?   =ka:{;!?=ka\
v   R                         R {{R:ak=?!\:$:'@=?!;{:/
v/?!/:$:'@=?!;}:ak= ?!;}:ak=?!\}\        }
y\=ka:L                      }{ /        }
\iuakrU      y<<              !  }}}L {{{L

Try it online!

Uncompressed (and almost readable) version:

>; "  O  n  l  y     a     F  e  w     B  u  g  s  "  @
                               ;           /                                 \
/y<<         R                         R {{R:ak=?!\:$:'@=?!;{:ak=?!\{:ak=?!\{/
RiuakrR:ak=?!/:$:'@=?!;}:ak= ?!/}:ak=?!\}\        }                ;
\y<<  U                               }{ /        }
      \                                !          L                     }}}L

Try it Online!

This...is about as close as I can get.

Compressing it further would require figuring out a way to handle the various loop swapping points without having them collide with other stuff. The first line (which is the only part needs to be passed as input to itself) is required to remain separate: the entire string can't fit on the second line without causing problems (_ for required spaces):

Needed string:
>; "  O  n  l  y  _  a  _  F  e  w  _  B  u  g  s
Best fit:
>; "  O  n  l  y  _  a  _  F  e  w/{_\!?   =ka:{;!?=ka\
Collision:                             ↑

That ? can't be moved away from the ! which itself can't be moved away from the \ and none of the allowable messages allow any of these three characters at this position.

The alternative would be to use flow redirection, but that leads to a problem on the lower line:

Last usable character:
            ↓
>"Only a Few Bugs"@
/.../
ur         }{L
              ↑
Earliest available free space:

As we have to avoid the loop switch in the main program.

Known issues:

  • Extremely large inputs. Due to Runic's IP stack limits, pushing very large input strings will cause the IP to expire before completing. This can be minimized by spawning additional IPs and merging them (for example, it handles abcdefghijklmnopqrstuvwxyz but not the entirety of its own source). And there's a limit regardless of how many merges occur. Can handle up to 58 bytes of input as-is (additionally, increasing the number of IPs requires figuring out how to get them to merge without using more space). Can fit two more IP entries on the loop-return line (to the right of the U on the line starting \y<< in the uncompressed version, or one left on the line above the y<< in the compressed version) raising the input max length to 78.
  • Input strings with spaces need to have the spaces escaped (e.g. 1\ \ 1\ \ +\ \ O\ \ @). This is a limitation of the language's input parsing.
  • Cannot supply inputs consisting of strings that look like integers beginning with any number of 0s (as when turned into a number on the stack, the 0 is lost). Again, limitation of the language's input parsing.

How it works

Entry:

  1. Combine 4 instruction pointers
  2. Read input, break into characters, append a newline, reverse, enter main loop.

Main loop (anything that pops the stack is preceded by a dup):

  1. Print the top of the stack
  2. Compare to newline. True: switch loops and rotate stack left twice.
  3. Compare to @. True: terminate. (Terminate command executed)
  4. Rotate stack right
  5. Compare to newline. True: terminate. (Rightmost command executed)
  6. Rotate stack right
  7. Compare to newline. True: switch loops and rotate stack left thrice.
  8. Rotate stack right
  9. Return to top of loop

Secondary loop:

  • Identical to main loop, only switch rotate right with rotate left
\$\endgroup\$
  • \$\begingroup\$ Err, are you trying to create a Backhand polyglot? The second program should be the result of running the first program with itself as input. Then the result of that program (when run in your original language, Runic) should be one of the phrases. From the question, you don't need to handle any actual Backhand instructions \$\endgroup\$ – Jo King Oct 3 '18 at 3:46
  • \$\begingroup\$ Your second program doesn't print anything. It just errors \$\endgroup\$ – Jo King Oct 3 '18 at 22:27
  • \$\begingroup\$ That's what I get when I apply the transformation to your original program. That should then print one of the phrases. Maybe you should have a second read of the question, or have a look at the other answers \$\endgroup\$ – Jo King Oct 3 '18 at 23:38
  • \$\begingroup\$ *Tries reading it again.* ...Nope, not seeing it yet... *Tries another time.* Oh! Christ, I did not understand it like that at all. I read it as "when your program reads its own source code as input" \$\endgroup\$ – Draco18s Oct 3 '18 at 23:46
  • \$\begingroup\$ @JoKing Is this right, then? \$\endgroup\$ – Draco18s Oct 4 '18 at 21:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.