# Nearest possible expressed number

A screen consists of some LED segments like such:

The screen can be split into several(maybe one) component. Each component is a segment like above, with varying lengths. These components can be used to display any amount, including 0, of digits, as long as the component is large enough.

Every digit except 1 needs two columns of the grid to be displayed. These columns are not allowed to overlap (even a number like 67 still needs 4 columns and does not fit into a n=2 component). The digit 1 is slim, so it only needs one column.

Therefore, a number fits into a component, iff 2 * Length - (Amount of 1's) <= n+1.

For example, the number 14617 can be displayed in a screen with the component lengths [0, 1, 1, 2, 0]:

Given the n's of each component and a positive integer, find the nearest positive integer that can be expressed in the screen. If multiple number are nearest, you can output either.

Shortest code wins.

# Examples

[1],3 => 3
[1],16 => 11
[0,0],3 => 1
[0,0],6 => 1 or 11
[2],14 => 14
[2],24 => 21
[3],999999999 => 1111
[1,0,0,0,0,0,1],23 => 23
[0,3],100 => 100

• Can digits on the same component overlap? e.g., would 88 be possible for n=2? What about 69 for n=2? Jul 1 at 15:01
• @Shaggy No, otherwise one can't even tell 13 from 8
– l4m2
Jul 1 at 15:09
• You use [3] as one of your examples but don't define it anywhere. What is it EEEI? Very unclear whatever it is. Also details on exactly what numbers EI can represent would be clearer. Jul 1 at 15:48
• Also, you need to more formally define what each number needs to look at and how 1 interacts with other numbers, since it only occupies one column - can a single n=2 grid represent both 18 and 81? It's not immediately clear. Jul 1 at 19:17
• Does 67 fit into an n=3, or do those not exist? Jul 2 at 0:42

# Ruby, 163 143 bytes

->r,i{g=->s,r{*t,c=s;d,*q=r;n=c==1?1:2;!c||d&&(n<d+2?g[t,[d-n,*q]]:g[s,q])}
h=->n,r{g[n.digits,r]&&p(n)}
a=0;until h[i+a,r]||h[i-a,r];a+=1;end}


Try it online!

-20 bytes thanks to @Kirill L.

My first golf in Ruby. I'm sure that it can be even shorter, but I didn't find anything.

### Explanation

g (takes an array of chars, representing the number, and the displays) checks if a given number fits into the given display. f then checks all numbers, starting with the given integer, then i+1, i-1, i+2, ..., and outputs the first number that fits.

• A few tips: the outer non-recursive function can be anonymous (so, you can omit f= from byte count). Then, Ruby has built-in digits method for integers. And loop break approach is almost always suboptimal, especially with several break conditions. Jul 4 at 19:05
• I also made a quick translation of my R answer to Ruby for 131 bytes, perhaps it can still be minified further. Jul 4 at 19:05

# Jelly, 29 bytes

n1‘S>
⁵*ḶD“”ṭçÐḟ
‘Ç€ŒpF€ḌạÐṂḢ


Try it online!

# Jelly, 34 bytes

‘Ø½ṗⱮẎS=¥ƇƲ€ŒpF€ị⁵Ḷṭ1¤Œp€ŒP€€ḌFạÞḢ


Try it online!

-2 bytes thanks to caird coinheringaahing

This is absolutely horrible. I won't be surprised if someone can halve my bytecount. I spent a decent bit of time on it; not too much - I'll keep golfing this but I think it's at least close to worth posting.

• 34 bytes Jul 2 at 19:49

# Python 3, 190181215 175 bytes

def f(n,i,m=["0"]):
for g in n:m=[u+x[1:]for u in m for x in[str(d)for d in range(0,12*i)if sum(-~(b!="1")for b in str(d))<g+3]]
return min(map(int,m),key=lambda v:abs(v-i))


Generates a roughly bounded list of possible ints for each segment, zero pads, tests each to see if they fit, permutates all the sequences for each segment, then finds closest int match to the input.

Thanks mypetlion and l4m2 for improving my swing!

Try it online!

• Change (2,1)[b=="1"] to -~(b!="1") to save 3 bytes. Jul 2 at 23:26
• You can also remove that space after for x in, and you don't have to use list(m) because m is already a list. Jul 2 at 23:27
• <=g+1 => <g+2?
– l4m2
Jul 3 at 2:06
• 2*10**g => 2*i, though some cases takes too much time then
– l4m2
Jul 3 at 2:13
• Failed
– l4m2
Jul 3 at 8:28

# Common Lisp, 337 bytes

(defun C(a b &aux r)(dolist(x a)(dolist(y b)(push(concatenate'string x y)r)))r)(defun P(n &aux r)(case n(0'("""1"))(1'("0""1""2""3""4""5""6""7""8""9""11"""))(t(dotimes(i n r)(setf r(,@r,@(C(P i)(P(- n i 1)))))))))(defun F (i x)(- x(reduce'min(mapcar(lambda(p)(-(or(parse-integer p :junk-allowed t)0)x))(reduce'C(mapcar'P i))):key'abs)))


Try it online!

Gets all possible numbers that can be represented by the given component list i, finds the smallest distance from the numbers to input x and returns x - distance.

F is the main function, C concatenates combinations, and P recursively gets the possible digits for a component of size n.

Testing included in TIO. This can probably maybe be reduced by 50-75 or so bytes as is, mainly the double dotimes in C, the disgusting string hell in P, and the :junk-allowed t in parse-integer used by F. The junk-allowed t was needed for the case where the string is empty. I at some point tried to replace all instances of dolist, reduce, defun, and mapcar with l, d, e, m respectively but the resulting code ended up being larger at 404 bytes but someone might be able to make use of it so I'm still putting it here:

(let((f(copy-tree'(progn(d C(a b &aux r)(l(x a)(l(y b)(push(concatenate'string x y)r)))r)(d P(n &aux r)(case n(0'("""1"))(1'("0""1""2""3""4""5""6""7""8""9""11"""))(t(dotimes(i n r)(setf r(,@r,@(C(P i)(P(- n i 1)))))))))(d F (i x)(- x(e'min(m(lambda(p)(-(or(parse-integer p :junk-allowed t)0)x))(e'C(m'P i))):key'abs)))))))(mapc(lambda(x y)(nsubst x y f))'(dolist defun reduce mapcar)'(l d e m))(eval f))


Try it online!

The code is essentially wrapped in

(let ((f (copy-tree '(progn CODE))))
(mapc (lambda (x y) (nsubst x y f))
'(THINGS TO BE REPLACED)
'(THINGS TO REPLACE THEM WITH))
(eval f))


# R, 148 147 bytes

function(n,m,g=function(n,s=nchar(n),d=2-!n%/%10^(0:s)%%10-1){for(i in m)while(s&&(i=i-d[s])>-2)s=s-1;n*!s}){while(!(r=max(g(n-F),g(n+F))))F=F+1;r}


Try it online!