将数字转换为代表最多“ 4”的基数


30

灵感来自。有一个数字,可以是整数,字符串或数字数组(您可以选择)。找到该数字表示形式将具有最多“ 4”的基数,然后返回该基数。

编号结果
624 5
444 10
 68 16

限制条件:

  • 返回的基数不应大于输入值。
  • 小于或等于abs(4)的数字不应视为有效输入,因此可接受未定义的返回值

这可能是任何代码高尔夫球代码的挑战。您能否详细说明要求,获胜标准,并可能给出一个或多个输入和所需输出的示例?
codeporn

最高可接受的基数是多少?
Steven Rumbalski

我认为是36岁,因为此后很难代表
SeanC

2
@SeanCheshire: You don't actually have to display the number. You can easily represent a number in any base as an array, such as [1,15,3,64,43] for some number in base 80. You're only outputting the base number, so you could technically test every base from 2 to n.
mellamokb

1
什么是正确的答案123,它们具有相同数量的“4” S在每个基地(0)?同样,许多数字在许多基数中具有相同的“ 4”数(例如,4在任何基数> 5,44在任何基数> 45,14在基数9或任何基数> 15等)。正确的答案应该是最小的底数最大的“ 4”吗?
mellamokb

Answers:


24

APL(31 19)

现在测试所有可能的基准。

⊃⍒{+/4=K⊤⍨K⍴⍵}¨⍳K←⎕

说明:

  • ⍳K←⎕: read user input, store in K. Make a list from 1 to K, which are the bases to try.
  • {...: for each of these, run the following function
  • K⊤⍨K⍴⍵: encode K into that base giving a list of digits (as numbers) per base. Use K digits (a big overestimate, but it doesn't matter because the unused ones will all be zero anyway).
  • 4=: see which of these are equal to 4
  • +/: sum these, now we know how many fours per base
  • ⊃⍒: give the indices of the list if it were sorted downwards, so the index of the biggest one is at the front. Take the first item of this list.

2
I love your APL solutions.
MrZander

25
Funny how that APL expression contains the expression most people make when reading it:
epidemian

5

GolfScript, 30 characters

.,{[2+.2$\base{4=},,\]}%$)~p];

Works for any base - test the code online.

Comment: This solution was based on the original version of the question. It thus may return a base larger than the input, e.g. for the input 4 it correctly returns base 5 - which is no longer valid by the new rules.


5

GolfScript (23 chars)

~:^,2>{^\base[4]/,~}$0=

or

~:^,2>{^\base[4]/,}$-1=

or

~:^,2>{^\base[4]/,}$)\;

Note that this takes input from stdin: for a fair comparison with Howard's GolfScript version subtract one char.


Howard points out that the rules have changed, and it's not very logical that they now exclude 4 as a possible input when it has a valid output (any integer greater than 4). To cover that case as well requires an extra 2 characters, which can be added in all kinds of ways:

~:^)),2>{^\base[4]/,}$)\;

or

~:^,{))^\base[4]/,}$)))\;

being a couple of the obvious ones.


Nice. But gives wrong answer for input "4".
Howard

I just saw that they changed the rules completely and removed any special cases after I did my submission. Thus your solution conforms to the new rules.
Howard

@Howard, the rules may say that that case doesn't need to be handled, but in the interests of completeness I'll add some variants.
Peter Taylor

Nevertheless, I can't +1 more than once ;-)
Howard

@Howard, you can add a bounty if you really want ;)
Peter Taylor

4

Python 2.x, 77 chars

F=lambda x:max((sum(x/b**d%b==4for d in range(99)),b)for b in range(5,99))[1]

Works up to base 98 and numbers at most 98 digits long.


4

J, 38 characters

f=.[:(i.>./)[:+/[:|:4=(10#"0(i.37))#:]

Usage:

   p 624
5
   p 444
10
   p 68
16

4

VBA, 121

Function k(a)
For w=5 To a
Z=0:q=a:Do:c=q Mod w:Z=Z-(c=4):q=Int(q/w):Loop Until q=0
If Z>x Then x=Z:k=w
Next
End Function

usage:

  • direct window: ?k(num)
  • Excel formula: =k(A1)

fixed for all bases, and reduced test to simply counting 4s
SeanC

FWIW, you can remove a space: For w=5To a
Engineer Toast

3

Mathematica 59

Code

Sort[{Count[IntegerDigits[n, #], 4], #} & /@ Range[5, 36]][[-1, 2]]

Let's give the above function a name.

whichBase[n_] := Sort[{Count[IntegerDigits[n, #], 4], #} & /@ Range[2, 36]][[-1, 2]]

Explanation

  1. Count[IntegerDigits[n,k],4]: Count the number of fours in the base k representation of n.
  2. Sort the bases from fewest to most 4s.
  3. Return the base from the last item in the list, that is, the base that had the representation with the most 4's.

Some special numbers

Now let's apply whichBase to the following special numbers.

numbers= {1953124, 8062156, 26902404, 76695844, 193710244, 444444444, 
943179076, 1876283764, 3534833124, 6357245164, 10983816964, 
18325193796, 29646969124, 46672774204, 71708377284, 107789473684, 
158856009316, 229956041484, 327482302084, 459444789604, 635782877604, 
868720588636, 1173168843844, 1567178659764, 2072449425124, 
2714896551724, 3525282954756, 4539918979204, 5801435550244, 
7359635486844, 9272428079044, 11606852190676}

{5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, \ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36}

If you convert each number to the corresponding base, you will see what is special about them.


I think you'd have to add 7 bytes for a complete function definition if you want to use n there. Also, MaximalBy really helps, knocks it down to 49 bytes: MaximalBy[Range[a=#],a~IntegerDigits~#~Count~4&]& (just ignore messages from it trying to use base-1)
LegionMammal978

Also, the current one fails starting on n = 152, where it gives 36 instead of 37.
LegionMammal978

Although your code works, I do not understand how it knows which bases to use. Shouldn't it need to be told to examine bases 2 through 36 (or 1 through 36)?
DavidC

Base 36 is never specified in the problem, and that's why I claim that yours fails for n = 152 = 4·37 + 4. My code checks all bases from 1 to n, since bases n + 1 and onward will only contain the single digit n.
LegionMammal978

Thanks for the clear explanation.
DavidC

3

Japt -h, 10 bytes

444 in base 10 is [4,4,4] which contains the number and digit 4 3 times but 444 in base 100 is [4,44] which also contains the digit 4 3 times, but only as a number once. Given the expected output in the challange for the 444 test case, I'd guess we're supposed to be counting the number 4:

õ ñ@ìX è¥4

Try it

But if we are counting the digit 4 then:

õ ñ@ìX ¬è4

Try it

õ              :Range [1,...,input]
  ñ@           :Sort by passing each X through a function
    ìX         :  Convert the input to a base X digit array
               :(VERSION 1)
       è       :  Count the elements
        ¥4     :    Equal to 4
               :(VERSION 2)
       ¬       :  Join to a string
        è4     :  Count the occurrences of "4"
               :Implicitly output the last element in the sorted array

2

C - (114 characters)

In all it's golfy glory:

x,k,c,d,n;main(v){scanf("%d",&v);for(k=5;v/k;++k){x=v;c=0;while(x)c+=x%k==4,x/=k;c>=d?n=k,d=c:0;}printf("%d",n);}

And somewhat ungolfed:

x,k,c,d,n; // declare a bunch of ints, initialized to 0
main(v){   // declare one more, without using an extra comma
    scanf("%d",&v); // get the input (v)
    for(k=5;v/k;++k){ // loop over each base (k) greater than or equal to (/)
                      // our input (v)
        x=v;          // temp value (x) set to input (v)
        c=0;          // number of 4s in the current base (c) re-initialized
        while(x)       // loop over our temp until it's used up
            c+=x%k==4, // if the next digit (x%k) is 4 (==4) increment the
                       // current count (c+=)
            x/=k;      // remove the current digit
        c>=d?n=k,d=c:0; // if the number of 4s in this base (c) is greater
                       // than the current maximum number of 4s (d), then
                       // save the new best base (n), and new maximum
                       // number of 4s
    }
    printf("%d",n);   // output the result
}

Just for fun here's the output for the numbers [0,127] (these are the largest bases under the input number itself).

0, 0, 0, 0, 0, 5, 6, 7, 8, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 5, 21, 22, 23, 6, 25, 26, 27, 7, 29, 30, 31, 8, 33, 34, 35, 9, 37, 38, 39, 10, 41, 42, 43, 11, 5, 46, 47, 12, 49, 50, 51, 13, 53, 54, 55, 14, 57, 58, 59, 15, 61, 62, 63, 16, 65, 66, 67, 17, 69, 5, 71, 18, 73, 74, 75, 19, 7, 78, 79, 20, 81, 82, 83, 21, 85, 86, 87, 22, 89, 90, 91, 23, 93, 94, 5, 24, 97, 98, 99, 25, 101, 102, 103, 26, 5, 106, 107, 27, 109, 5, 111, 28, 113, 114, 5, 29, 9, 5, 5, 5, 121, 122, 123


1
@AttilaO. I was hoping someone would notice :)
Gordon Bailey

2

R - 148 137 chars

(so, far away from the rest of the competition but still)

f=function(n){s=sapply;which.max(s(lapply(strsplit(s(4:n,function(x){q=n;r="";while(q){r=paste(q%%x,r);q=q%/%x};r})," "),`==`,4),sum))+3}

Basically transform the input from base 10 to all bases from 4 to n (using modulo %% and integer division %/%) and pick the index of the first one having the most 4s.

f(624)
[1] 5
f(444)
[1] 10

2

J translation of @marinus' APL solution:

NB. Expression form (22 characters, not including "n" - the "argument"):
{.\:(+/@(4=$#:[)"0 i.)n
NB. Function form (24 characters, not including "f=:"):
f=:{.@\:@(+/@(4=$#:[)"0 i.)

Just for interest, here are some values:

(,.f"0)9+i.24
 9  5
10  6
11  7
12  8
13  9
14  5
15 11
16  6
17 13
18  7
19  5
20  5
21  5
22  5
23  5
24  5
25  6
26  6
27  6
28  6
29  5
30  7
31  7
32  7

It outputs the smallest base that gives a fouriest transform. For the last few values in the table, the representations look like “4n” (e.g 31 in base 7 is “43”).


2

Jelly, 6 bytes

bⱮċ€4M

Try it online!

Outputs "all" bases up to N which gives the most 4's. If you want maximal or minimal base, add (max) or (min) respectively.

How it works

bⱮċ€4M    Main link (monad). Input: integer N.
bⱮ        Convert N to each base of 1..N
  ċ€4     Count 4's in each representation
     M    Take maximal indices

2

05AB1E, 10 9 bytes

LBε4¢}Zk>

-1 byte thanks to @Cowabunghole.

If multiple bases have the same amount of 4s, it will output the smallest one (i.e. 16 will result in 6, but 12 would also have been a possible output).

Try it online or verify all test cases.

Explanation:

L           # Create a list in the range [1, (implicit) input]
            #  i.e. 624 → [1,2,3,...,622,623,634]
 B          # Convert the (implicit) input integer to Base-N for each N in this list
            #  i.e. 624 and [1,2,3,...,622,623,624]
            #   → ["1","1001110000","212010",...,"12","11","10"]
  ε  }      # Map this list to:
   4¢       #  Count the number of 4s in the number
            #   → [0,0,0,0,4,0,0,0,0,1,0,2,...,0,0,0]
      Z     # Take the max (without popping the list)
            #  i.e. [0,0,0,0,4,0,0,0,0,1,0,2,...,0,0,0] → 4
       k    # Get the index of this max in the list
            #  i.e. [0,0,0,0,4,0,0,0,0,1,0,2,...,0,0,0] and 4 → 4
         >  # Increase it by to convert the 0-index to our base (and output implicitly)
            #  i.e. 4 → 5

Couldn't you replace Qƶà with k>? i.e. find the 0-based index of the max and increment it?
Cowabunghole

@Cowabunghole Ah, you're indeed right. Not sure how I missed that. Thanks!
Kevin Cruijssen

1

C# with Linq 273

using System;using System.Linq;class P{static void Main(){int r,z,k=int.Parse(Console.ReadLine());if(k<=4) return;Console.WriteLine(Enumerable.Range(4, k).Select(x =>{r = 0;z = k;while (z > 0){if(z % x==4){r++;}z/=x;}return new[]{r, x};}).OrderBy(n => n[0]).Last()[1]);}}

or

using System;
using System.Linq;

class P
{
    static void Main()
    {
        int r, z, k = int.Parse(Console.ReadLine());
        if (k <= 4) return;
        Console.WriteLine(
            Enumerable.Range(4, k).Select(x =>
                {
                    r = 0;
                    z = k;
                    while (z > 0)
                    {
                        if (z % x == 4)
                        {
                            r++;
                        }
                        z /= x;
                    }
                    return new[] { r, x };
                }).OrderBy(n => n[0]).Last()[1]);

    }
}

Pretty sure the number of variables can be reduced and the if's can be converted to ?s. Oh well...


1

C# (482 ~423 Bytes)

First attempt at a 'golfed' solution. I used basically the same algorithm as the VBA above. I could probably save some bytes inlining the conversion function, or shortening the name. Like I said this is a first attempt, so please be gentle.

With whitespace:

using System;
class Program
{
    static void Main(string[] args)
    {
        int n = int.Parse(args[0]);
        int c=0, m=0;
        string r="";
        int t = 0;
        for (int i = 5; i < 37; i++)
        {
            while (n > 0)
            {
                r = (char)((int)(n % i) + 48 + (7 * ((int)(n % i) > 9 ? 1 : 0))) + r;
                n = (int)(n / i);
            }
            t = r.Length - r.Replace("4", "").Length;
            if (t > c) { c = t; m = i; }
        }
        Console.WriteLine("Base: " + m);
    }
}

4
I don't think the namespace is required. All names should be a single character, including Program and cBase. And yes, you should inline cBase. Also, combine declaration and initialization, i.e., int c=0,m=0.
mellamokb

2
Also, it looks like you've combined your test code with the function code that performs the logic. The spec requires an input of a number/string of digits, and the output of an integer. It would be fair to simply create a function that takes int parameter, and returns int parameter, without even a Main method, and call the character count your score.
mellamokb

@mellamokbtheWise - I learned something new. I always assumed the namespace was required. Also, good catch on the test array, that saves me some chars, and I am now actually answering the challenge.
theB

1

Burlesque - 28 bytes

Jbcjro{dg}Z]J{4CN}Cmsb[~Fi?i
Jbcjro                        create a list 1..input and convert input
                              to an infinite list.                      
      {dg}Z]                  convert number to base (zipWith operation)
            J                 duplicate
             {4CN}Cm          create comparison function 
              4CN             count the number of fours.
                    sb        sort by 
                      [~      take the last element (which is going to be
                              the base-n representation where count of fours
                              is highest)
                        Fi    Find the index of this last element in the original
                              unsorted list
                          ?i  increment (because base 1 is index 0)

Try it online.


there you go. (see the edit or click tio.run/##SyotykktLixN/…)
mroman

1

k, 18 bytes

{*>+/'4=x{y\x}'!x}

Try it online!

{                } /function(x)
        x     '!x  /for every y in 0, 1, ..., (x-1):
         {y\x}     /    do x in base y
      4=           /see which digits equal four
   +/'             /sum, to get number of 4s per base
 *>                /get index (which equals base) of largest number of 4s


1

Husk, 9 bytes

S€►#4ṠMBḣ

Try it online!

 €           The 1-based index in
      MB     the list of the input's representations in every base
     Ṡ  ḣ    from 1 to itself
S ►          of its element which has the largest
   #         number of
    4        fours.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.