关于基本二进制文件


29

请原谅标题。

这是一个受82000的“好奇属性”启发的问题。在其中,作者指出数字82000在2、3、4和5的底数是二进制的。该帖子然后提出了一个问题:“在2、3、4、5和6的底数中是否有二进制数? “?(对于那些好奇的人,我检查了高达10 ^ 1,000,000的值,到目前为止,答案是否定的。)

这让我开始思考:给定一个数字,它的二进制基础什么?

我们的奇数82000实际上是六个基数的二进制数:

Base 2 = 10100000001010000
Base 3 = 11011111001
Base 4 = 110001100
Base 5 = 10111000
Base 81999 = 11
Base 82000 = 10

并非所有数字都具有连续的二进制基数。考虑数字8321。它是以2、17、289、83520和8351为基数的二进制数。

您面临的挑战是确定并显示数字的二进制基础。

规则

  • 如果数字在给定基数中的表示形式仅由零和一组成,则该数字被视为“二进制”。 110110是二进制值,而12345不是,A380F则绝对不是。
  • 您的电话号码将在标准输入中提供。它是2到2 ^ 32-1之间的整数值(包括2和32 ^ 32-1),并将以10为基数的格式提供。
  • 以升序显示大于2的二进制数的每个基数。每个基数应位于其自己的行上。如果您在该基数中包含二进制值(请参阅下面的加分评分),请用空格分隔基数和二进制值。将仅判断输出到标准输出,将忽略标准误差和其他来源。

计分

您的分数是程序的大小(以字节为单位)。分数越低越好。

奖励
如果您的程序还以找到的基数输出二进制值,则将分数乘以0.75。
显示的二进制值应该没有多余的标点符号,没有多余的零,没有小数点,只有零和一。

例子

输入:

82000

输出(收到奖金):

2 10100000001010000
3 11011111001
4 110001100
5 10111000
81999 11
82000 10

输入:

1234321

输出(无奖金):

2
1111
1234320
1234321

输入可以以换行符结尾吗?
LegionMammal978

@ LegionMammal978-嗯...确定吗?我的意图是,您应该能够使用简单的fgets,readline或类似的东西来获取输入数字。
骆马先生2015年

1
一般情况下,n总是至少在二进制基础1(未计数), ,2n-1n
mbomb007

1
当您说“将在标准输入中提供您的电话号码”时,您的意思仅是STDIN,还是我们可以像站点的标准电话号码那样接受该号码作为函数参数?
Alex A.

二进制表示形式(在奖金部分中)是否应具有某种格式?尤其[1, 0, 1, 1, 0]可以,或者是否必须像这样将数字加起来10110
Jakube 2015年

Answers:


14

珀斯,14 13

jbf!-jQTU2tSQ

感谢Jakube指出了新S功能。

在这里尝试。

在线版本太慢了1234321。这只是将输入的每个底数从2转换为自身,并丢弃包含0和1以外的值的结果。

说明:

                           : Q=eval(input) (implicit)
jb                         : join on newlines the list...
  f!                       : filter away nonempty values (impliticly named T)
    -jQTU2                 : sewtise difference of number converted to base and range(2)
     jQT                   : convert Q to base T
        U2                 : range(2)
          tSQ              : over the range [2 Q+1)

另外,这是(打高尔夫球不好现在好golfed,再次感谢Jakube)奖金版(20 * 0.75 = 15):

VQI!-JjQK+2NU2pdKjkJ

在这里尝试


Pyth刚刚更新。因此,您可以链接到实际的解决方案。
Jakube 2015年

这是20 * 0.75 = 15的解决方案:VQI!-JjQK+2NU2pdKjkJ有时函数式编程不是最佳方法。
Jakube 2015年

10

朱莉娅 72 70字节

奖金实际上更长一些,所以这里没有奖金。

n=int(readline());for j=2:n all(i->i0:1,digits(n,j))&&println(j)end

这将从STDIN读取一行,将其转换为整数,然后打印结果。尽管是蛮力方法,但输入1234321对我而言却不到1秒。

取消+说明:

# Read n from STDIN and convert to integer
n = int(readline())

# For every potential base from 2 to n
for j = 2:n
    # If all digits of n in base j are 0 or 1
    if all(i -> i0:1, digits(n, j))
        # Print the base on its own line
        println(j)
    end
end

例子:

julia> n=int(readline());for j=2:n all(i->i0:1,digits(n,j))&&println(j)end
1234321
2
1111
1234320
1234321

julia> n=int(readline());for j=2:n all(i->i0:1,digits(n,j))&&println(j)end
82000
2
3
4
5
81999
82000

注意:如果可以将输入作为函数参数而不是从STDIN作为参数(等待来自OP的确认),则解决方案为55个字节。



7

Mathematica,59个字节

Print/@Select[1+Range[n=Input[]],Max@IntegerDigits[n,#]<2&]

啊... IntegerDigits D:

关于代码,实际上没有太多解释。使用STDIN和STDOUT的要求浪费了12个字节。

我认为我无法领取奖金。我得到的最好的是84个字节(得分超过60):

Print@@@Select[{b=#+1," ",##&@@n~IntegerDigits~b}&/@Range[n=Input[]],Max@##3<2&@@#&]

7

蟒蛇2,88 86 80

相当简单,没有奖金。Python对全局变量很友好。

N=input();g=lambda n:n<1or(n%b<2)*g(n/b)
for b in range(2,N+1):
 if g(N):print b

我设法获得的最佳奖金是118 * .75 = 87.75

N=input();g=lambda n:0**n*" "or" "*(n%b<2)and(g(n/b)+`n%b`)*(g(n/b)>'')
for b in range(2,N+1):
 if g(N):print`b`+g(N)

不错的解决方案,用短得多的代码击败了我。
卡德2015年

只做g(N)而不是做会更短n=N
feersum

@feersum哦,是的(以前是g(N,b)这样,逗号使两个相等),但是您的意思是我不需要N的变量?
KSab 2015年

@KSab我删除了第二部分;没关系
feersum 2015年

我可能是错的,但您不能仅通过更改g(n/b)(g(n/b)+'n%b')“代表反引号” 来获得奖金?
feersum 2015年

4

蟒蛇2,90 * 0.75 = 67.5

n=input();b=1
while b<n:
 b+=1;s="";c=k=n
 while k:s=`k%b`+s;c*=k%b<2;k/=b
 if c:print b,s

非常简单的迭代方法。

没有奖金,这是73个字节:

n=input();b=1
while b<n:
 b+=1;c=k=n
 while k:c*=k%b<2;k/=b
 if c:print b

4

SQL(PostgreSQL),247.5 255 230.25(307 * .75)

由于众所周知SQL在这些挑战方面很出色,所以我认为我最好将它们放在一起:)对于这一挑战,奖金确实是值得的。
它应该符合规范,但是我没有简单的方法来测试COPY I FROM STDIN
编辑固定订单。更改了处理列R的方式以使用数组。

CREATE TABLE IF NOT EXISTS I(I INT);TRUNCATE TABLE I;COPY I FROM STDIN;WITH RECURSIVE R AS(SELECT n,I/n I,ARRAY[I%n] R FROM generate_series(2,(SELECT I FROM I))g(n),(SELECT I FROM I)I(I)UNION ALL SELECT n,I/n,I%n||R FROM R WHERE I>0)SELECT n||' '||array_to_string(R,'')FROM R WHERE 2>ALL(R)and i=0ORDER BY n

作为测试,我只是在I表中使用了直插。试运行扩大并发表了评论。

-- Create the table to accept the input from the copy command
CREATE TABLE IF NOT EXISTS I(I INT);
-- Make sure that it is empty
TRUNCATE TABLE I;
-- Popoulate it with a value from STDIN
--COPY I FROM STDIN;
INSERT INTO I VALUES(82000); -- Testing
--Using a recursive CTE query
WITH RECURSIVE R AS (
    -- Recursive anchor
    SELECT n,                -- base for the row
       I/n I,                -- integer division
       ARRAY[I%n] R   -- put mod value in an array
    FROM generate_series(2,(SELECT I FROM I))g(n), -- series for the bases
         (SELECT I FROM I)I(I) -- Cross joined with I,  saves a few characters
    UNION ALL 
    -- for each row from r recursively repeat the division and mod until i is 0
    SELECT n,
        I/n,
        I%n||R -- Append mod to beginning of the array
    FROM R WHERE I>0
    )
-- return from r where i=0 and r has 1's and 0's only
SELECT n||' '||array_to_string(R,'')
FROM R 
WHERE 2 > ALL(R)and i=0
ORDER BY n -- Ensure correct order

2 10100000001010000
3 11011111001
4 110001100
5 10111000
81999 11
82000 10


很近!输出基数必须按升序排列。+1但使用非常规语言。
骆马先生2015年

@Llama先生用固定了它order by。现在看看我是否可以找回这些角色
MickyT 2015年

3

Haskell 109 * 0.75 = 81.75字节

0#x=[]
n#x=n`mod`x:div n x#x 
f n=[show x++' ':(n#x>>=show)|x<-[2..n+1],all(<2)$n#x]
p=interact$unlines.f.read

使用示例(注意:二进制值首先是lsb):

p 82000

2 00001010000000101
3 10011111011
4 001100011
5 00011101
81999 11
82000 01

没有输入/输出限制,即通过函数参数输入,通过REPL以本机格式输出):

Haskell,67 * 0.75 = 50.25字节

0#x=[]
n#x=n`mod`x:div n x#x
f n=[(x,n#x)|x<-[2..n+1],all(<2)$n#x]

返回(基,值)对的列表。值首先是lsb,例如(添加了换行符/空格以便更好地显示):

 f 82000
 [ (2,[0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,1]),
   (3,[1,0,0,1,1,1,1,1,0,1,1]),
   (4,[0,0,1,1,0,0,0,1,1]),
   (5,[0,0,0,1,1,1,0,1]),
   (81999,[1,1]),
   (82000,[0,1]) ] 

2

R,111

目前可能还有很多空间可以改善此问题

i=scan();b=2:i;R=i%%b;I=rep(i,i-1);while(any(I<-I%/%b))R=cbind(I%%b,R);for(x in b)if(all(R[x-1,]<2))cat(x,'\n')

带有警告运行

> i=scan();b=2:i;R=i%%b;I=rep(i,i-1);while(any(I<-I%/%b))R=cbind(I%%b,R);for(x in b)if(all(R[x-1,]<2))cat(x,'\n')
1: 82000
2: 
Read 1 item
There were 17 warnings (use warnings() to see them)
2 
3 
4 
5 
81999 
82000
>

@AlexA。I%/%bany()子句中将强制强制为逻辑引起的警告。`
MickyT

2

Java 181 155.25(207 * .75) 151.5(202 * .75)字节

class I{public static void main(String[]a){a:for(long b=new java.util.Scanner(System.in).nextLong(),c,d=1;d++<b;){String e="";for(c=b;c>0;e=c%d+e,c/=d)if(c%d>1)continue a;System.out.println(d+" "+e);}}}

扩展说明:

class I {
    public static void main(String[]a){
        a:for(long b=new java.util.Scanner(System.in).nextLong(),c,d=1; //b = input(), d = base
              d++<b;) {                                           //For all bases in range(2,b+1)
            String e="";
            for(c = b;c > 0; e = c % d + e,c /= d)                //Test all digits of base-d of b
                           //e = c % d + e                        //Append digits to string
                if (c % d > 1)                                    //Reject base if the digit is greater than 1
                    continue a;
            System.out.println(d+" "+e);                          //Print base and digits.
        }
    }
}

原始(无奖金):

class I{public static void main(String[]a){long b=new java.util.Scanner(System.in).nextLong(),c,d=1;a:for(;d++<b;){c=b;while(c>0){if(c%d>1)continue a;c/=d;}System.out.println(d);}}}

3.75字节感谢Ypnypn :)


2

电话,94 83 79

n=scan();cat((2:n)[!sapply(2:n,function(x){while(n&n%%x<2)n=n%/%x;n})],sep="\n")

用法:

> n=scan();cat((2:n)[!sapply(2:n,function(x){while(n&n%%x<2)n=n%/%x;n})],sep="\n")
1: 82000
2: 
Read 1 item
2
3
4
5
81999
82000
> n=scan();cat((2:n)[!sapply(2:n,function(x){while(n&n%%x<2)n=n%/%x;n})],sep="\n")
1: 1234321
2: 
Read 1 item
2
1111
1234320
1234321

函数的核心是!sapply(2:n,function(x){while(n&n%%x<2)n=n%/%x;n}),对于从2到n的每个基数x,只要余数为0和1,就保持商n / x。然后输出结果(如果所有余数均为1或0,则结果为0。 0)并将其取反(0取为TRUE,其他所有取值为FALSE)。由于函数作用域,因此无需为n创建一个虚拟变量。然后将布尔向量的所得向量用于索引2:n,因此仅输出其工作的基数。


1

TI-Basic,45个字节

Input N
For(B,2,N
If prod(seq(BfPart(iPart(N/B^X)/B),X,0,log(N)/log(B))<2
Disp B
End

说明

  • 输入N
  • 从2到N的每个B
    • 如果在基数B中N仅为0和1
      • 显示B
  • 结束循环

复杂的部分

第二行的工作方式如下:

  • 对于从0到log B的每个X N的
  • B×fPart(iPart(N / B X)/ B)是基数B中的第N个数字,向后计数
  • 将此视为清单
  • 对于每个元素,如果数字小于2,则产生1(真),否则产生0(假)
  • 拿乘积:1如果所有元素都是1

注意

如果将括号)放在第二行的末尾,则该程序的运行速度将显着提高。有关更多信息,请参见此处


1

TI-BASIC,31 29

For(B,2,Ans
If 2>round(Bmax(fPart(Ans/B^randIntNoRep(1,32
Disp B
End

对于TI-BASIC,这可能是最佳选择。

说明:

randIntNoRep(1,32)返回一个从1到32的数字的随机排列(我们需要的是以某种顺序排列的数字; TI-BASIC没有APL的iota命令之类的东西)。32个元素就足够了,因为可能的最小底数是2,最大数是2 ^ 32-1。B^randIntNoRep(1,31)将该列表提高到Bth幂,结果该列表包含所有B^1,B^2,...,B^32(按某种顺序)。

然后将输入(以Answer变量形式输入[number]:[program name])用该数字除。如果您输入的是42,底数是2,则结果将是列表21,10.5,5.25,...,42/32,42/64,[lots of numbers less than 1/2],再次以某种顺序进行。

将小数部分乘以基数即可得出基数b中该位置的数字。如果所有数字均小于2,则最大数字将小于2。

如Ypnypn所述,For由于解析器错误,语句的右括号使此操作加快了速度。

31-> 31:保存了一个字节,但是修复了舍入错误,该错误再次增加了该字节。

31-> 29:使用RandIntNoRep()代替节省了两个字节cumSum(binomcdf())


TI-BASIC是否具有序列功能?
骆马先生2015年

是的,命令是seq(expression, variable, start, end[, step])。如果未给出任何步骤,则默认为1。但是,cumSum(binomcdf(31,0为8个字节,而seq(X,X,1,32为9个字节。
飞鸟

嗯,这可以解释。我对TI-Basic中的评分工作不熟悉。
骆马先生2015年

1

果冻,9字节

³bṀỊµÐfḊY

在线尝试!

聊天中Caird共同完成

怎么运行的

完整程序。

     Ðf过滤隐式生成的范围[1,输入]。
    µ启动新的单子链。
³b将输入转换为列表的当前数字的基数。
  Ṁ最大。
   Ị无关紧要的。检查abs(Z)≤1。
       Ḋ出队;删除列表的第一个元素(删除基数1)。
        Y通过换行符加入。

0

Javascript,ES6、118 * .75 = 88.5 110 * .75 = 82.5

f=x=>{res={};for(b=2;b<=x;++b)if(!+(res[b]=(c=x=>x%b<2?x?c(x/b|0)+""+x%b:"":"*")(x)))delete res[b];return res}

先前版本:

f=x=>{res={};for(q=2;q<=x;++q)if(!+(res[q]=(c=(x,b)=>x%b<2?x?c(x/b|0,b)+""+x%b:"":"*")(x,q)))delete res[q];return res}

校验:

f(82000)
Object { 2: "10100000001010000", 3: "11011111001", 4: "110001100", 5: "10111000", 81999: "11", 82000: "10" }

在这里,您没有输入,也没有输出。
edc65

0

JavaScript( ES6)65

带有参数和控制台输出的函数的68个字节。

f=n=>{s=n=>n%b>1||b<n&&s(n/b|0);for(b=1;b++<n;)s(n)||console.log(b)}

65个字节,通过弹出窗口进行I / O

n=prompt(s=n=>n%b>1||b<n&&s(n/b|0));for(b=1;b++<n;)s(n)||alert(b)

领取奖金:88 * 0.75 => 66

n=prompt(s=n=>n%b>1?9:(b<=n?s(n/b|0):'')+n%b);for(b=1;b++<n;)s(n)<'9'&&alert(b+' '+s(n))

0

Mathematica,76 * 0.75 = 57

n=Input[];G=#~IntegerDigits~b&;If[Max@G@n<2,Print[b," ",Row@G@n]]~Do~{b,2,n}

最初忘记了输入要求...幸运的是,这些并没有增加太多额外的内容。



0

Perl 5 5,63个字节

map{$t=$n;1while($f=$t%$_<2)&&($t=int$t/$_);say if$f}2..($n=<>)

在线尝试!

在这方面没有任何奖金,因为它的得分比我的奖金得分略高:

Perl 5,85个字节* 0.75 = 63.75

map{my$r;$t=$n;$r=$/.$r while($/=$t%$_)<2&&($t=int$t/$_);say"$_ 1$r"if$/<2}2..($n=<>)

在线尝试!

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.