How many Lynch-Bell numbers are there?

19

1

Challenge

Given an integer, n, as input where 36 >= n >= 2, output how many Lynch-Bell numbers there are in base n.

The output must be in base 10.

Lynch-Bell Numbers

A number is a Lynch-Bell numbers if:

  • All of its digits are unique (no repetition of digits)
  • The number is divisible by each of its digits
  • It doesn't contain zero as one of its digits

Since, all of the digits have to be unique, and you have a finite set of single digit numbers in each base, there is a finite number of Lynch-Bell numbers.

For example, in base 2 there is only one Lynch-Bell number, 1, since all other numbers either repeat digits or contain a 0.

Examples

Input > Output
2 > 1
3 > 2
4 > 6
5 > 10
6 > 10
7 > 75
8 > 144
9 > 487
10 > 548

Mathematica Online ran out of memory above base 10. You can use the following code to generate your own:

Do[Print[i," > ",Count[Join@@Permutations/@Rest@Subsets@Range[#-1],x_/;And@@(x\[Divides]FromDigits[x,#])]&[i]],{i,10,36,1}]

Winning

Shortest code in bytes wins.

Beta Decay

Posted 2017-09-11T15:53:37.490

Reputation: 21 478

1@MagicOctopusUrn Why do we need a dictionary? We don't need to output in that base. – user202729 – 2017-09-11T16:01:54.677

@BetaDecay That will turns the problem into a kolmogorov-complexity one. – user202729 – 2017-09-11T16:02:25.797

@user202729 Yep, I've edited it now – Beta Decay – 2017-09-11T16:03:18.010

@MagicOctopusUrn Sorry I didn't read the problem specification carefully. Output ... in base n. – user202729 – 2017-09-11T16:05:19.317

2could you add an example >10? – Rod – 2017-09-11T16:05:51.697

The output does not actually need to be in base n, right? ("...output how many Lynch-Bell numbers there are in base n" appears to have caused some confusion.) – Jonathan Allan – 2017-09-11T16:07:54.827

1@JonathanAllan I see, I've cleared that up now – Beta Decay – 2017-09-11T16:08:38.583

3If only [2-36] need be supported we may as well list them all. – Jonathan Allan – 2017-09-11T16:09:12.160

Related, also related – James – 2017-09-11T16:11:22.287

That I've said, No, up to 36 should be fine will turns the problem into a kolmogorov-complexity one. – user202729 – 2017-09-11T16:11:23.823

http://oeis.org/A034838 may be helpful. – Magic Octopus Urn – 2017-09-11T16:41:20.180

3Turns out that no one has managed to calculate f(36). Make a fastest-code challenge based on this would be probably interesting. – user202729 – 2017-09-25T10:15:38.947

Answers

8

Jelly, 13 bytes

Q⁼g
*`Ṗ©bç"®S

Try it online!

Another O(nn) solution.

Explanation

Q⁼g  Helper link. Input: digits (LHS), integer (RHS)
Q    Unique (digits)
 ⁼   Match
  g  GCD between each digit and the integer

*`Ṗ©bç"®S  Main link. Input: integer n
*`         Compute n^n
  Ṗ        Pop, forms the range [1, n^n-1]
   ©       Store previous result in register
    b      Convert each integer to base n
     ç"    Call the helper link, vectorized, with
       ®   The register's value
        S  Sum

miles

Posted 2017-09-11T15:53:37.490

Reputation: 15 654

16 bytes ṖŒPḊŒ!€Ẏ⁼g¥"ḅ¥³S and faster – miles – 2017-09-11T18:46:14.697

5

Jelly, 15 bytes

*ḃ€’Q€Qḍḅ¥€⁸Ạ€S

Try it online!

Complexity O(nn).

Leaky Nun

Posted 2017-09-11T15:53:37.490

Reputation: 45 011

5Only in code-golf is an O(N^N) solution not only acceptable, but good. – James – 2017-09-11T16:55:20.127

5@DJMcMayhem Meh, I think we can pump those numbers up and get O(N↑↑N) – Beta Decay – 2017-09-11T17:15:12.100

Should it be O(N^(N+1)) because check the validity of each generated number takes O(N)? (although I don't understand Jelly) – user202729 – 2017-09-12T09:44:14.837

@user202729 N+1 is just N in big-O notation. – mbrig – 2017-09-12T14:10:39.993

1@mbrig Of course I understand big-O notation, that (N+1 is in O(N)) does not implies N^(N+1) is in O(N^N). – user202729 – 2017-09-12T14:16:33.193

3

Java, 222 212 190 bytes

-10 bytes thanks to Herman

-22 bytes thanks to Kevin

import java.util.*;a->{int c=0,i=1;A:for(;i<Math.pow(a,a);i++){Set g=new HashSet();for(char b:a.toString(i).toCharArray())if(!g.add(b)|b<49||i%a.parseInt(b+"",a)>0)continue A;c++;}return c;}

Ungolfed:

a -> {
    int count = 0;
    OUTER:
    for (int i = 1; i < Math.pow(a, a); i++) {
        Set<Character> found = new HashSet<>();
        for (char b : Integer.toString(i, a).toCharArray()) {
            if (!found.add(b) || b == 48 || i % Integer.parseInt(b + "", a) != 0) {
                continue OUTER;
            }
        }
        count++;
    }
    return count;
}

Try it online!

Gets very slow for large numbers.

Okx

Posted 2017-09-11T15:53:37.490

Reputation: 15 025

-10 bytes: a->{int c=0,i=1;A:for(;i<Math.pow(a,a);i++){java.util.Set<Character>g=new java.util.HashSet<>();for(char b:Long.toString(i,a).toCharArray())if(!g.add(b)|b<49||i%Long.parseLong(b+"",a)>0)continue A;c++;}return c;} – Herman L – 2017-09-11T18:58:16.157

One of the first times I've seen a label used in a codegolf answer – Justin – 2017-09-11T22:45:04.737

A: and continue A; are 13 bytes while {--c;break;} is 12. Would that instroduce some bug I don't see? – JollyJoker – 2017-09-12T07:58:08.487

This might be worth a separate answer, but you can loop through the digits in base n by each digit being i%a and i/=a at each loop. You can avoid the set by using an int[] and checking that x[b]++<2 – JollyJoker – 2017-09-12T08:14:54.237

java.util.Set<Character>‌​g=new java.util.HashSet<>(); can be import java.util.*; + Set g=new HashSet();; Long.toString can be a.toString; and Long.parseLong can be a.parseInt. – Kevin Cruijssen – 2017-09-12T12:54:18.357

@KevinCruijssen Thanks a lot! – Okx – 2017-09-12T15:34:51.300

3

Perl 6, 86 84 77 bytes

-2 bytes thanks to Ramillies

->\n{n-1+grep {.Set==$_&&.reduce(* *n+*)%%.all},map {|[X] (1..^n)xx$_},2..^n}

Try it online!

Works for n=8 on TIO.

nwellnhof

Posted 2017-09-11T15:53:37.490

Reputation: 10 037

1I think you can save 2 bytes by doing .all instead of all $_. – Ramillies – 2017-09-11T20:58:45.920

2

Mathematica, 82 79 76 bytes

Count[Join@@Permutations/@Subsets@Range[#-1],x_/;x==x~FromDigits~#~GCD~x]-1&

user202729

Posted 2017-09-11T15:53:37.490

Reputation: 14 620

How do you pass a number into this? (sorry, Mathematica is new to me) – Beta Decay – 2017-09-11T16:12:08.313

Paste the function (e.g., to Wolfram sandbox), and then put [<parameter>] after that. With parameter being a number. – user202729 – 2017-09-11T16:13:46.703

Can you add a TIO, or equivalent? – Shaggy – 2017-09-11T16:21:40.370

1

@Shaggy https://www.wolframcloud.com/objects/025b270d-d293-4459-a8f4-2cfb7e769f21

– Beta Decay – 2017-09-11T16:24:30.090

1Are f(5) and f(6) both really 10? That's odd... – Magic Octopus Urn – 2017-09-11T16:25:01.610

@BetaDecay The link will likely to expire soon. – user202729 – 2017-09-11T16:27:05.877

@user202729 Hm that's a shame – Beta Decay – 2017-09-11T16:27:53.293

@BetaDecay It works for 2 and 10. – Mr. Xcoder – 2017-09-11T16:36:12.823

@Mr.Xcoder Never mind, I was mistaken – Beta Decay – 2017-09-11T16:38:32.913

2

Actually, 24 bytes

;╗DR⌠╜DR╨i⌡M⌠;╜@¿♀%ΣY⌡MΣ

Try it online!

Explanation

This program consists of two main parts: the permutation generation, and the Lynch-Bell test. So, this explanation will look at each part separately, for greater clarity.

Generating Permutations

Input: n (an integer in [2, 36])

Output: all partial and total permutations of [1, n-1] (sequences containing values from [1, n-1] without repetition whose length is in [1, n-1])

;╗DR⌠╜DR╨i⌡M
;╗            store a copy of n in register 0
  DR          range(1, n)
    ⌠╜DR╨i⌡M  do the following for each element k in range:
     ╜DR        range(1, n)
        ╨       k-permutations of [1, n-1]
         i      flatten

Lynch-Bell Test

Input: a list of base-n integers, represented as lists of base-n digits

Output: the number of Lynch-Bell numbers in base n

⌠;╜@¿♀%ΣY⌡MΣ
⌠;╜@¿♀%ΣY⌡M   for each base-n digit list a:
 ;╜             duplicate a, push n
   @¿           convert a from base-n to decimal
     ♀%         modulo a with each of its base-n digits
       Σ        sum
        Y       boolean negation (1 if all modulo results are 0, else 0)
           Σ  sum (count the 1s in the resultant list)

Mego

Posted 2017-09-11T15:53:37.490

Reputation: 32 998

1

05AB1E, 22 bytes

mLIBε0KÙ}ÙvyIöySIö%O_O

Try it online!

O_O was also my face when this finally worked.

<ÝIBJ0Kæ¦Ù€œ˜ is faster than the way I use to generate the numbers in the actual answer but randomly stops working for anything bigger than 7 (for no apparent reason?)

Explanation

mLIBε0KÙ}ÙvyIöySIö%O_O # (input = i)
m                      # Push i^i
 L                     # ...and get a range from one to this value
  IB                   # Map every element to their base i representation
    ε   }              # Map every element to ...
     0K                 # Itself without 0s
       Ù                # ...and only unique digits
         Ù             # Uniquify the resulting list
          v            # For each element...
           yIö          # Push it converted to base 10
              ySIö      # Push every digit of it converted to base 10 in a list
                  %     # Calculate the modulo for each digit
                   O    # Sum all results together
                    _   # Negate: Returns 0 for every positive number and 1 for 0
                     O  # Sum with the rest of the stack (Basically counting all Lynch-Bell-Numbers)
                       # Implicit print

Datboi

Posted 2017-09-11T15:53:37.490

Reputation: 1 213

I'm pretty sure a different approach can save more bytes, but in your current solution ε0KÙ} can be 0м€Ù to save a byte. – Kevin Cruijssen – 2019-02-25T10:44:12.290

1

Perl 5, 80 76 bytes (75 + -p)

$\+=!grep$_?$;%$_|$|{0,$_}++:1,@@until($@[$}++]+=1)%=$_ and++$;,$}=$}==$_}{

Abusing $; for fun and profit. Times out on inputs > 8.

EDIT: -4 bytes by merging the two loops.

Grimmy

Posted 2017-09-11T15:53:37.490

Reputation: 12 521

1

Ruby, 80 65 bytes

->n{(1..n**n).count{|i|(d=i.digits n)-[0]==d|d&&d.sum{|j|i%j}<1}}

Try it online!

Thanks to G B for -15 bytes.

Kirill L.

Posted 2017-09-11T15:53:37.490

Reputation: 6 693

This won't work for n>10 (because of "j.to_i") – G B – 2019-02-25T09:42:16.423

Good catch, too bad it times out well before that :) – Kirill L. – 2019-02-25T09:44:41.783

Anyway: you could call "digits" passing the base as argument and save a lot: ->n{(1..n**n).count{|i|(d=i.digits n)-[0]==d|d&&d.sum?{|j|i%j}<0}} – G B – 2019-02-25T09:58:17.090

Indeed I absolutely missed that digits has this parameter. But I see you had posted this as a separate answer and then deleted. I'd say, go ahead, you beat me to it :) – Kirill L. – 2019-02-25T10:25:49.687

I think my answer is too similar, it's the same approach with a couple of shortcuts, mostly stolen code. – G B – 2019-02-25T11:57:03.763

OK, then thanks for your help. – Kirill L. – 2019-02-25T12:43:08.673

1

Japt -x, 25 19 bytes

-6 bytes thanks to Shaggy

pU õìU ËeDâ f myDìU

Try it online!

ASCII-only

Posted 2017-09-11T15:53:37.490

Reputation: 4 687

20 bytes? – Shaggy – 2019-02-26T10:52:11.837

Or 19 bytes with the -x flag.

– Shaggy – 2019-02-26T10:54:31.723

wow O_o i'm clearly terrible at golfing japt – ASCII-only – 2019-02-26T11:11:03.807

You're doing well so far :) It takes time to get to grips with a new language, figure out all its features, tricks & quirks. – Shaggy – 2019-02-26T11:14:08.867

@Shaggy but when you use a new language as often as I do it should be expected that I'd be closer to optimal than like 25% XD – ASCII-only – 2019-02-26T11:50:54.673

0

Python 3, 204 174 bytes

lambda x,r=range,i=chain:sum(0**any(int(''.join(map(str,y)),x)%z for z in y)for y in i(*map(permutations,i(*[combinations(r(1,x),e)for e in r(x)]))))-1
from itertools import*

Try it online!

For each permutation of each element of powerset of range(1,n) (no zeros, unique), convert to numerical string to base n. Sum all that are divisible by each digit, subtract 1 due to powerset generating the empty set.

-30 bytes thanks to @ovs!

Conner Johnston

Posted 2017-09-11T15:53:37.490

Reputation: 146

184 bytes – ovs – 2017-09-11T19:03:48.843

174 bytes – ovs – 2017-09-11T19:06:58.677

0

Haskell, 117 bytes

f n=sum[1|x<-id=<<[mapM(\_->[1..n-1])[0..m]|m<-[0..n]],all(\y->[mod(sum(zipWith((*).(n^))[0..]x))y|c<-x,c==y]==[0])x]

Try it online! Works on TIO up to n=7 before timing out.

Laikoni

Posted 2017-09-11T15:53:37.490

Reputation: 23 676

0

Perl 5, 108 + 1 (-p) = 109 bytes

while(@a<$_){$r=%k=@a=();for($t=++$i;$t;$t=int$t/$_){push@a,$t%$_}$r||=!$_||$i%$_||$k{$_}++for@a;$r||$\++}}{

Try it online!

It's a pig. Not sure if it will do more than base 8 on TIO without timing out.

Xcali

Posted 2017-09-11T15:53:37.490

Reputation: 7 671

0

C# (Visual C# Interactive Compiler), 144 bytes

n=>{int j,i,p;for(j=i=0;i++<~0UL;){p=i;var a=new List<int>();for(;p>0;p/=n)a.Add(p%n);j+=a.All(c=>c>0&&i%c<1&a.Count(x=>x==c)<2)?1:0;}return j;}

Goes through all the numbers from 0 to ulong.MaxValue, and selects those that are Lynch-Bell numbers in the specified base. Takes forever to run, even for 2, though if you set the ~0UL part in the for loop to something smaller, you can get output for input up to 7 within a minute on TIO.

Try it online!

Embodiment of Ignorance

Posted 2017-09-11T15:53:37.490

Reputation: 7 014