a.k.a. You Can Output Anything With Labyrinth Or HexagonyTM
Challenge
In a recent restricted-source 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 restricted-source challenge in the form of:
Given the characters
.@and a subset of0-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
Nare inD. - The Labyrinth program
N.@prints the characterc, i.e.N % 256 == ord(c).- The byte value of
ccan be anything between 1 and 255 inclusive.
- The byte value of
- 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 code-golf 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
13 Answers 13
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`)
-
1\$\begingroup\$
D=>c=>eval(`for(;/[^${D}]/.test(c);)c+=256;c`)is only 46 bytes. \$\endgroup\$Neil– Neil2021年04月27日 00:05:21 +00:00Commented Apr 27, 2021 at 0:05 -
\$\begingroup\$ @Neil I was indeed trying to get rid of
kbut you're faster than me. Thank you. :-) \$\endgroup\$Arnauld– Arnauld2021年04月27日 00:09:20 +00:00Commented 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– tsh2021年04月27日 02:05:20 +00:00Commented Apr 27, 2021 at 2:05
Jelly, (削除) 15 (削除ここまで) (削除) 10 (削除ここまで) 9 bytes
Ɠ+9$Dḟ3Ɗ¿
-1 byte thanks to Jonathan Allan
Full program that takes D as the first argument and c in STDIN
How it works
Ɠ+9$Dḟ3Ɗ¿ - Main link. Takes D on the left
Ɠ - Read c from STDIN, set N = c
¿ - While:
Ɗ - Condition:
D - Digits of N
ḟ3 - Remove all elements of D
This is an empty list (falsey) iff all digits of N are in D
$ - Body:
+9 - Add 256 to N
-
1\$\begingroup\$ Here is a full-program version accepting the list as an argument and the ordinal from STDIN for 9 bytes. \$\endgroup\$Jonathan Allan– Jonathan Allan2021年04月27日 12:49:05 +00:00Commented Apr 27, 2021 at 12:49
-
\$\begingroup\$ @JonathanAllan Oh, nice! \$\endgroup\$2021年04月27日 12:55:07 +00:00Commented Apr 27, 2021 at 12:55
Scala, 59 bytes
d=>n=>Stream.from(1)find(x=>s"$x".forall(d.toSet)&x%256==n)
Just a brute force solution.
Charcoal, 19 bytes
NθW−⪪Iθ1⪪η1≧+256θ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θ1⪪η1
Filter out the digits of D from the digits of N. While some remain, ...
≧+256θ
... add 256 to N.
Iθ
Output the final value of N.
J, 29 24 22 bytes
(]256&+~0 e.e.~&":)^:_
-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.
-
-
\$\begingroup\$ Oh that's very nice. \$\endgroup\$Jonah– Jonah2021年04月27日 04:21:18 +00:00Commented Apr 27, 2021 at 4:21
Haskell, (削除) 38 (削除ここまで) 34 bytes
- -4 bytes thanks to xnor, for using
until.
f d=until(all(`elem`d).show)(+256)
Takes d as a list of Chars (i.e. a String) and c as an integer.
-
1
-
\$\begingroup\$ @xnor indeed it does :D \$\endgroup\$Delfad0r– Delfad0r2021年04月27日 07:38:26 +00:00Commented Apr 27, 2021 at 7:38
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.
Python 3, 45 bytes
f=lambda d,c:f(d,c+256)if{*str(c)}-{*d}else c
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.
-
2\$\begingroup\$ Here, due to
fneeding a space before it if using theand-ortrick, it actually does not save any bytes to apply that here. But in case you're interested,a if b else cis generally replaceable byb and a or cwhich saves up to a byte by default and maybe more or less depending on characters that need spaced. The notable exception is ifamay be false. \$\endgroup\$2021年04月27日 07:42:36 +00:00Commented Apr 27, 2021 at 7:42
R, 68 bytes
f=function(D,C)"if"(all((utf8ToInt(paste(C))-48)%in%D),C,f(D,C+256))
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}
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.