15
\$\begingroup\$

a.k.a. You Can Output Anything With Labyrinth Or Hexagony™

Challenge

In a recent challenge, I could print any character with only half of the allowed digits with very small character count, by abusing the "digit commands" and modulo-256 output function. Now, it's about time to make a general metagolfer for this kind of challenges.

For the sake of simplicity, we only consider Labyrinth programs of the form <digits>.@, i.e. construct a number, print it modulo 256 as character code, and halt. Also, the sequence of digits acts exactly like a number literal in this case.

Now let's assume we want to solve a challenge in the form of:

Given the characters .@ and a subset of 0-9, print a character.

Given a subset of digits D and the target character c, find the shortest number N which will solve the hypothetical challenge above. In other words, N should satisfy the following:

  • All the digits of N are in D.
  • The Labyrinth program N.@ prints the character c, i.e. N % 256 == ord(c).
    • The byte value of c can be anything between 1 and 255 inclusive.
  • Out of all possible Ns satisfying the above, your program should output one that has the shortest length. If there are multiple possible answers, your program is free to output any of them.

You may take c as a character or an integer (charcode), and digits in D as integers or digit characters. Also, you may assume D is already sorted.

Assume the answer exists. Note that some conditions will lead to "no answer", e.g. only odd digits are allowed but you need to print an even character, or vice versa. You may assume that such conditions will never be given as input.

Standard rules apply. The shortest code in bytes wins.

Test cases

The value of c is given as its character code.

D = [1, 2, 3, 4, 5]
c = 1 => N = 1
c = 57 => N = 313
c = 254 => N = 254
c = 100 => N = 1124 or 4452
c = 107 => N = 1131, 2155, 2411, or 3435

D = [1, 2, 4, 6, 8]
c = 58 => N = 826
c = 71 => N = 1111111
c = 255 => N = 26111

D = [7]
c = 49 => N = 777777
\$\endgroup\$

13 Answers 13

7
\$\begingroup\$

JavaScript (ES6), 46 bytes

Saved 6 bytes thanks to @Neil

Expects (D)(c), where D is a string of digits and c is an integer.

D=>c=>eval(`for(;/[^${D}]/.test(c);)c+=256;c`)

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ D=>c=>eval(`for(;/[^${D}]/.test(c);)c+=256;c`) is only 46 bytes. \$\endgroup\$
    – Neil
    Apr 27, 2021 at 0:05
  • \$\begingroup\$ @Neil I was indeed trying to get rid of k but you're faster than me. Thank you. :-) \$\endgroup\$
    – Arnauld
    Apr 27, 2021 at 0:09
  • 3
    \$\begingroup\$ But recursive is shorter: D=>g=c=>eval(`/[^${D}]/`).test(c)?g(c+256):c \$\endgroup\$
    – tsh
    Apr 27, 2021 at 2:05
6
\$\begingroup\$

Jelly, 15 10 9 bytes

Ɠ+⁹$Dḟ³Ɗ¿

Try it online!

-1 byte thanks to Jonathan Allan

Full program that takes D as the first argument and c in STDIN

How it works

Ɠ+⁹$Dḟ³Ɗ¿ - Main link. Takes D on the left
Ɠ         - Read c from STDIN, set N = c
        ¿ - While:
       Ɗ  -   Condition:
    D     -     Digits of N
     ḟ³   -     Remove all elements of D
                This is an empty list (falsey) iff all digits of N are in D
   $      -   Body:
 +⁹       -     Add 256 to N
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Here is a full-program version accepting the list as an argument and the ordinal from STDIN for 9 bytes. \$\endgroup\$ Apr 27, 2021 at 12:49
  • \$\begingroup\$ @JonathanAllan Oh, nice! \$\endgroup\$ Apr 27, 2021 at 12:55
3
\$\begingroup\$

Scala, 59 bytes

d=>n=>Stream.from(1)find(x=>s"$x".forall(d.toSet)&x%256==n)

Try it in Scastie!

Just a brute force solution.

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

Charcoal, 19 bytes

NθW⁻⪪Iθ¹⪪η¹≧⁺²⁵⁶θIθ

Try it online! Link is to verbose version of code. Takes input of N and D as a string. Explanation:

Nθ

Input N as an integer.

W⁻⪪Iθ¹⪪η¹

Filter out the digits of D from the digits of N. While some remain, ...

≧⁺²⁵⁶θ

... add 256 to N.

Iθ

Output the final value of N.

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

Stax, 8 bytes

πdµ∞╔▓|▒

Run and debug it

Explanation

WcEx-!CVB+
W          loop forever
 c         copy c
  E        get digits
   x       push D
    -      set difference
     !C    if empty, break out of the loop
       VB+ else add 256   
\$\endgroup\$
3
\$\begingroup\$

Japt, 13 12 bytes

Takes D as an array and c as an integer, in reverse order.

@ìkV}f@±X©G²

Try it

\$\endgroup\$
2
\$\begingroup\$

J, 29 24 22 bytes

(]256&+~0 e.e.~&":)^:_

Try it online!

-2 thanks to Bubbler

Call it like: 1 2 3 4 5 f 57, which returns 313.

  • ]256&+~...^:_ Keep adding 256 while...
  • 0 e.e.~&": There is a digit of the right arg that's not in the left arg.
\$\endgroup\$
2
  • \$\begingroup\$ 22 bytes using & trick on the inner ^:. \$\endgroup\$
    – Bubbler
    Apr 27, 2021 at 4:19
  • \$\begingroup\$ Oh that's very nice. \$\endgroup\$
    – Jonah
    Apr 27, 2021 at 4:21
2
\$\begingroup\$

Haskell, 38 34 bytes

  • -4 bytes thanks to xnor, for using until.
f d=until(all(`elem`d).show)(+256)

Try it online!

Takes d as a list of Chars (i.e. a String) and c as an integer.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Your recursive function looks quite a bit like an until: TIO \$\endgroup\$
    – xnor
    Apr 27, 2021 at 7:36
  • \$\begingroup\$ @xnor indeed it does :D \$\endgroup\$
    – Delfad0r
    Apr 27, 2021 at 7:38
1
\$\begingroup\$

Retina, 36 bytes

"$<%'"~L$`.+$
/[^$&]/+`.+¶$$.($*257*

Try it online! Takes N and D on separate lines but test suite splits on , for convenience. Explanation:

"$<%'"~`

Evaluate the following generated Retina program passing in only N as input.

L$`.+$

Use D to generate the Retina program.

/[^$&]/+`

The generated program repeats while N contains a digit not in D.

.+¶$$.($*257*

Each loop of the generated program adds 256 to N. This is a little unclear due to the quoting. The generated program looks like this:

/[^12468]/+`.+
$.(*_[256 more `_`s]

The *_ converts N to unary. The 256 _s then effectively adds 256, after which the $.( converts the sum to decimal.

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

Python 3, 45 bytes

f=lambda d,c:f(d,c+256)if{*str(c)}-{*d}else c

Try it online!

My first attempt at golfing in Python (or, for that matter, in an imperative language). Suggestions are welcome! Especially about conditionals, I don't really know all those and and or tricks, but I almost never see if-else used in Python codegolfing, so I guess I'm doing something wrong :).

Also, I had to increase the default recursion limit for some testcases, I hope that's ok.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Here, due to f needing a space before it if using the and-or trick, it actually does not save any bytes to apply that here. But in case you're interested, a if b else c is generally replaceable by b and a or c which saves up to a byte by default and maybe more or less depending on characters that need spaced. The notable exception is if a may be false. \$\endgroup\$
    – hyper-neutrino
    Apr 27, 2021 at 7:42
1
\$\begingroup\$

Python 3, 70 bytes

d,n=set(input()),ord(input())
while not set(str(n))<=d:n+=256
print(n)

Try it online! Simple brute-force solution.

\$\endgroup\$
0
\$\begingroup\$

Python 3, 82 bytes

f=lambda d,c,k=0:(all(_ in d for _ in str(k))and chr(k%256)==c)and k or f(d,c,k+1)

Try it online!

Plain brute force, takes D as a string of the numbers and c as a character.

\$\endgroup\$
0
\$\begingroup\$

R, 68 bytes

f=function(D,C)"if"(all((utf8ToInt(paste(C))-48)%in%D),C,f(D,C+256))

Try it online!

Fails in TIO for larger test-cases.


without recursion:

R, 75 bytes

function(D,C){while(T%%256-C|any(!(utf8ToInt(paste(+T))-48)%in%D))T=T+1;+T}

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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