32
\$\begingroup\$

I need to prepare digits made of cardboard to display some number (example). I don't know beforehand which number I should display - the only thing I know is that it's not greater than n.

How many cardboard digits should I prepare?

Example: n = 50

To display any number in the range 0...50, I need the following digits:

  1. A zero, for displaying the number 0, or any other round number
  2. Two copies of digits 1, 2, 3 and 4, for displaying the corresponding numbers
  3. One copy of digits 5, 6, 7 and 8, for the case they appear as least significant digit in the number
  4. The digit 9 is never needed, because I can use the inverted digit 6 instead

Total: 13 digits

Test cases (each line is a test case in the format "input; output")

0 1
1 2
9 9
11 10
50 13
99 17
100 18
135 19
531 22
1000 27
8192 34
32767 38
\$\endgroup\$
  • 2
    \$\begingroup\$ Can any other digit be rotated besides 6/9? \$\endgroup\$ – feersum Jun 24 '17 at 20:55
  • \$\begingroup\$ No (see example) \$\endgroup\$ – anatolyg Jun 24 '17 at 21:19
  • \$\begingroup\$ So two 1's can't be overlaid to make a 7 then \$\endgroup\$ – immibis Jun 26 '17 at 5:34
  • 2
    \$\begingroup\$ ... and two zeros cannot make a 8. That would be ugly. \$\endgroup\$ – anatolyg Jun 26 '17 at 7:12
  • \$\begingroup\$ Probably an awkward question, but as these are 'cardboard' digits, can they be double-sided printed to save on the total required? In the example, you would never need 6 and 0 together, for instance. \$\endgroup\$ – Weckar E. Jun 26 '17 at 11:13
16
\$\begingroup\$

Jelly, 9 bytes

‘ḶDœ|/ḟ9L

Try it online!

How it works

‘ḶDœ|/ḟ9L
‘Ḷ         [0,1,...,n]
  D        convert each to list of its digits
   œ|/     fold by multiset union
      ḟ9   remove 9
        L  length
\$\endgroup\$
  • 14
    \$\begingroup\$ Too fast >.< I swear, you have a Jelly answer for every known challenge in the universe and you just have a bot to post them right after the challenge. :P Nice answer. \$\endgroup\$ – HyperNeutrino Jun 24 '17 at 20:39
  • 10
    \$\begingroup\$ @HyperNeutrino I think the bot extracts testcases from the challenge and tries every possible jelly program using a supercomputer. \$\endgroup\$ – NieDzejkob Jun 25 '17 at 8:09
  • 1
    \$\begingroup\$ @HyperNeutrino You know the feeling...especially if your solution is 0rDŒr€ẎQṪÞẎḟ9ĠẎL. \$\endgroup\$ – Erik the Outgolfer Jun 25 '17 at 15:15
  • \$\begingroup\$ I doubted the validity of ḟ9 part for a moment, then I realised 6 < 9 so number of 6s can't be less than the total possible number of 6s and 9s combined in each combination. \$\endgroup\$ – Nader Ghanbari Jun 11 '18 at 16:13
7
\$\begingroup\$

Python 2, 49 bytes

lambda n:9*len(`n`)-9+(n*9+8)/10**len(`n`)+(n<10)

Try it online!

A clumsy arithmetical formula. Assume that n fits within an int so that an L isn't appended.

Thanks to Neil for saving 5 bytes by pointing out that 9's being unused could be handled by doing n*9+8 instead of n*9+9, so that, say, 999*9+8=8999 doesn't roll over to 9000.

\$\endgroup\$
  • \$\begingroup\$ @ovs That doesn't quite work, it's not enough to know the first digit. For example 33333 requires five 3's but 22222 requires only four. n*9[0] is tempting, but fails for numbers starting with 1 and less that 111... \$\endgroup\$ – xnor Jun 25 '17 at 6:07
  • \$\begingroup\$ By my calculations (see my Batch answer) you can probably use (n*9+8)/10**len(`n`) to avoid using min. \$\endgroup\$ – Neil Jun 25 '17 at 10:13
7
\$\begingroup\$

Haskell, 117 114 108 95 89 88 87 84 82 63 bytes

6 bytes saved thanks to Laikoni

1 4 6 bytes saved thanks to nimi

g x=sum[maximum[sum[1|u<-show y,d==u]|y<-[0..x]]|d<-['0'..'8']]

Try it online!

\$\endgroup\$
  • 3
    \$\begingroup\$ 1.) maximum[a,b] is the same as max a b. 2.) List comprehensions are often shorter than filter: max d$sum[1|x<-show a,x==b] \$\endgroup\$ – Laikoni Jun 25 '17 at 21:57
  • 1
    \$\begingroup\$ You can replace g with a pointfree function literal: sum.(#[-9..]). \$\endgroup\$ – nimi Jun 26 '17 at 15:29
  • \$\begingroup\$ @nimi I don't know what a pointfree function literal is, but I think I see what you are suggesting. Tell me if I'm wrong. \$\endgroup\$ – Sriotchilism O'Zaic Jun 26 '17 at 15:31
  • 1
    \$\begingroup\$ ... and length[x|x<-...] is sum[1|x<-...]. \$\endgroup\$ – nimi Jun 26 '17 at 15:32
  • 1
    \$\begingroup\$ Functions can be unnamed, so no need for the g= (but maybe you want to include it in the TIO version). \$\endgroup\$ – nimi Jun 26 '17 at 15:35
5
\$\begingroup\$

Mathematica, 49 bytes

Tr@Delete[Max~MapThread~DigitCount@Range[0,#],9]&
\$\endgroup\$
  • \$\begingroup\$ nice! Is this based on my answer? \$\endgroup\$ – J42161217 Jun 25 '17 at 4:16
5
\$\begingroup\$

JavaScript (ES6), 60 53 bytes

f=(n,i=9)=>n>(i%9+1+"e"+(i/9|0))/9-1?1+f(n,-~i):n>9^1

A sort of hacky recursive solution. This generates the numbers which require adding a digit:

1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 22, 33, 44, 55, 66, 77, 88, 100, 111, 222, ...

and then counts how many are less than the input. By a happy miracle, removing the digit 9 actually removes several bytes from the function, because the sequence can then be generated like so (assuming integer division):

1e1 / 9 = 1, 2e1 / 9 = 2, ..., 8e1 / 9 = 8, 9e1 / 9 = 10, 1e2 / 9 = 11, 2e2 / 9 = 22, ...

We do have to take into account the fact that numbers under 10 still require the zero, but this is as simple as adding n > 9 ? 0 : 1 to the result.

Test cases

let f=(n,i=9)=>n>(i%9+1+"e"+(i/9|0))/9-1?1+f(n,i+1):n>9^1;

[0, 1, 9, 11, 50, 99, 100, 135, 531, 1000, 8192, 32767].map(n => console.log(f(n)));

\$\endgroup\$
  • \$\begingroup\$ n>9^1 can probably be n<10 \$\endgroup\$ – CalculatorFeline Jun 25 '17 at 17:49
  • \$\begingroup\$ @CalculatorFeline Well, that gives true for input 0, so I'm a little hesitant to do that. \$\endgroup\$ – ETHproductions Jun 25 '17 at 18:31
  • \$\begingroup\$ 0>9 is false, false^1 is 1...? \$\endgroup\$ – CalculatorFeline Jun 25 '17 at 18:35
  • \$\begingroup\$ @CalculatorFeline Yes, I'm saying I'm hesitant to output the boolean true in place of the number 1. \$\endgroup\$ – ETHproductions Jun 25 '17 at 18:36
4
\$\begingroup\$

Batch, 67 bytes

@if %1 geq 10%2 %0 %1 0%2 -~%3
@cmd/cset/a(%1*9+8)/10%2+9*%30+!%30

In the standard formulation of this problem, you need separate 6 and 9 digits, but you're not required to display 0. As the maximum value n required increases, the number of required numerals increases every time you reach a repdigit (because you don't quite have enough of that numeral) and every time you reach a power of 10 (when you need an extra zero). In total each power of 10 needs 10 more numerals than the previous one, which can be caluclated as floor(log10(n))*10. For values of n between powers of 10, the number of intermediate repdigits can then be calculated as floor(n/((10**floor(log10(n))*10-1)/9)) or alternatively floor(n*9/(10**floor(log10(n))*10-1)).

I calculate floor(log10(n)) by means of the loop on the first line. Each time, %2 gains an extra 0 and %3 gains an extra -~. This means that 10%2 is 10*10**floor(log10(n)) and %30 is floor(log10(n)).

The duplication of 6 and 9 has two effects: firstly, there are only 9 numerals required for each power of 10, and secondly the repdigit detection needs to ignore the 9 repdigits. Fortunately as they are one less than a power of 10 this can be achieved by tweaking the formula to result in floor((n*9+8)/(10**floor(log10(n))*10)).

Dealing with the zero is reasonably simple: this just requires an extra numeral when n<10, i.e. floor(log10(n))==0.

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

Mathematica, 83 bytes

v=DigitCount;s=v@0;(Table[s[[i]]=v[j][[i]]~Max~s[[i]],{i,10},{j,#}];s[[9]]=0;Tr@s)&
\$\endgroup\$
1
\$\begingroup\$

Python 3, 75 bytes

lambda n:sum(max(str(j).count(str(i))for j in range(n+1))for i in range(9))

Try it online!

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

PHP, 60 bytes

<?=count(preg_grep('#^100+$|^([0-8])\1*$#',range(0,$argn)));

Try it online!

\$\endgroup\$

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.