输出“适合”数字


21

“适合人数”

山姆有一个“聪明”的压缩想法!你能帮我吗?


这是Sam压缩方案的简要说明。首先采用严格小于2 ^ 16的任何自然数的基数10表示形式,并将其写为没有任何前导零的二进制字符串。

1-> 1
9-> 1001
15-> 1111
13-> 1101
16-> 10000
17-> 10001
65535-> 111111111111111

现在,用一个零替换一个或多个零的任何组。这是因为这个数字越来越少了。您的二进制字符串现在将如下所示。

1-> 1-> 1
9-> 1001-> 101
15-> 1111-> 1111
13-> 1101-> 1101
16-> 10000-> 10
17-> 10001-> 101
65535-> 111111111111111-> 111111111111111

现在,您将二进制字符串转换回以10为基数的表示形式,并以任何可接受的格式输出。这是您的测试案例。第一个整数表示输入,最后一个整数表示输出。请注意,有些数字不会改变,因此可以称为“适合”

1-> 1-> 1-> 1
9-> 1001-> 101-> 5
15-> 1111-> 1111-> 15
13-> 1101-> 1101-> 13
16-> 10000-> 10-> 2
17-> 10001-> 101-> 5
65535-> 1111111111111111-> 1111111111111111-> 65535
65000-> 1111110111101000-> 11111101111010-> 16250


您可以使用任何语言,但请注意,Sam讨厌标准漏洞。这是代码高尔夫球,因此代码可以尽可能短,以便为“压缩数字”腾出空间。
注意:这不是可接受的压缩方案。使用此功能将立即使您被解雇。
需要引证:我不相信这个概念。这来自@Conor O'Brien的博客请参见此适合数字的OEIS。https://oeis.org/A090078


1
从@康纳尔的漫画博客:链接
Rɪᴋᴇʀ

3
OEIS A090078可能派上用场。
阿德南

是我写漫画的。<s>我还希望35%的代表专利使用费(</ s>;)
Conor O'Brien

请拒绝者解释这个问题吗?
Rohan Jhunjhunwala

1
为什么16等于8?16不应该10000吗?
eithed

Answers:


10

05AB1E8 6字节

b00¬:C

说明

b        # convert input to binary
 00¬:    # replace 00 with 0 while possible
     C   # convert to int

在线尝试

感谢Adnan,节省了2个字节


您可以替换„00'000¬:)。
阿德南

@Adnan尼斯!没想到。
Emigna '16

我什至不知道为什么我明确地将它们推成字符串……
Emigna '16

是的,这有点违反直觉,但是它可以工作:)。
阿德南

看起来它会赢:D,我会给它更多的时间来接受,以便更多的人参与。
Rohan Jhunjhunwala


7

JavaScript(ES6),41个字节

n=>+`0b${n.toString(2).replace(/0+/g,0)}`

7

水母,20字节

p
d
# S
,1
*
\dbi
 2

在线尝试!

说明

  • i 输入。
  • b 将其转换为二进制(数字列表)
  • \d带有参数2和数字列表d(数字的二进制数字)适用于数字列表的每个length-2子字符串。
  • * 取结果的符号:00变为0,其他所有值为1。
  • ,1 将1固定到末尾,因此最后一位不会丢失。
  • # Sbi上面计算出的列表中具有1的那些数字中选择:那些不是左半数00的那些数字。
  • d转换回数字,并p打印结果。

6

Python 2,36个字节

f=lambda n:n and f(n/2)<<(n%4>0)|n%2

没有内置转换或字符串操作的直接递归实现。少打高尔夫球:

f=lambda n:n and[f(n/2),n%2+2*f(n/2)][n%4>0]

n为4的倍数时,它以二进制的两个0结尾。因此,我们将其除以2会将其底数除以1。否则,我们将拆分n(n%2) + 2*(n/2),不保留最后一个二进制数字n%2,然后递归其他数字n/2


不是n%2多余的吗?
xsot

@xsot不确定您的意思。这样做|n会导致错误的结果。
xnor

我的意思是你可以替换整个的(n%4>0)|n%2使用(n%4>0)
xsot

@xsot优先级为(f(n/2)<<(n%4>0)) | n%2
xnor

啊,那我不好。我认为转移的优先级最低。
xsot

5

Bash(sed + bc),60 55 43字节

echo $[2#`bc<<<obase=2\;$1|sed s/00\*/0/g`]

编辑:

  1. 更改sed -E 's/0+为,sed 's/00*并更改了用于将值传递给bc的echo和管道<<<
  2. @Digital Trauma的精彩建议!

例:

$ bash script.sh 65000
16250
$ bash script.sh 15
15
$ bash script.sh 9
5

1
sed + bc也是我的第一个想法。echo "obase=2;$1"|bc|sed 's/00*/0/g;s/^/ibase=2;/'|bc是短2个字节
赖利

1
使用管道和逃生管可以发挥自己的优势:echo $[2#`bc<<<obase=2\;$1|sed s/00\*/0/g`]。但是,dctr 使其更短
Digital Trauma

1
@DigitalTrauma:谢谢,太好了!@Riley:好主意,它会像这样更短:bc<<<"obase=2;$1"|sed 's/00*/0/g;s/^/ibase=2;/'|bc
Master_ex

如果使用tr -s 0sed而不是sed,则可以减少到36个字节
Riley

@Riley:是的,但是Digital Trauma已经在其他bash答案中使用了它,所以我不想使用它:)
Master_ex

4

Perl 6的 31  27个字节

{:2(.base(2).subst(:g,/0+/,0))}
{:2(.base(2)~~{S:g/0+/0/})}

说明:

-> $_ {
  # convert from base 2
  :2(

    # convert to base 2
    $_.base(2)

    # substitute
    .subst(
      :global,
      / 0+ /,  # all substrings made of 0s
      '0'      # with one 0
    )
  )
}

例:

my &fit-compress = {:2(.base(2)~~{S:g/0+/0/})}
say fit-compress 1;     # 1
say fit-compress 9;     # 5
say fit-compress 15;    # 15
say fit-compress 13;    # 13
say fit-compress 16;    # 2
say fit-compress 17;    # 5
say fit-compress 65535; # 65535
say fit-compress 65000; # 16250

# number created with 「:2( [~] <0 1>.roll: 256 )」
say fit-compress 80794946326210692074631955353531749442835289622757526957697718534769445507500
# 4240335298301026395935723255481812004519990428936918

4

MATL,11 9 8字节

BFFOZtXB

该版本仅在MATLAB中有效,因为strrep在MATLAB中可以处理逻辑输入。这是一个可以使用Octave(9字节)(因此是在线解释器)工作的版本,该版本将逻辑输入明确转换为type double

在线尝试

说明

    % Implicitly grab input
B   % Convert decimal to binary
FF  % Create the array [0 0]
O   % Number literal
Zt  % Replaces all [0 0] with [0] (will replace any number of 0's with 0)
XB  % Convert binary to decimal
    % Implicitly display

4

Python 3中,55,50个字节。

Sp3000节省了4个字节。

非常简单的解决方案。

import re
f=lambda x:eval(re.sub('0+','0',bin(x)))

4
您可以保留0beval而是吗?
Sp3000

@ Sp3000当然可以!谢谢你的建议!
Morgan Thrapp '16

允许匿名lambda;您可以使用lambda x:eval(re.sub('0+','0',bin(x))) <insert newline here> import re
MilkyWay90,

3

Javascript(ES6),40个字节

n=>'0b'+n.toString(2).replace(/0+/g,0)-0

1
I'm afraid this is a snippet. Unless the challenge description states otherwise, the solutions are expected to be either full programs or functions.
manatwork

What require to be "full program" in Javascript if I don't want to use function? Please advise.
cychoi

For example with Node.js: console.log(+('0b'+parseInt(process.argv[1]).toString(2).replace(/0+/g,0))).
manatwork

Off topic. Your code block has the same problem as @Master_ex. Is it because some popular shell config scripts polluting the terminal? Or SE's fault?
cychoi

1
The shortest fix would be to prepend N=> which would make it a valid function submission.
Martin Ender

3

Actually, 14 bytes (non-competing)

├`'0;;+(Æ`Y2@¿

Try it online!

This submission is non-competing because a bugfix for Æ was made after this challenge was posted.

Explanation:

├`'0;;+(Æ`Y2@¿
├               bin(input) (automatically discards leading zeroes)
 `'0;;+(Æ`Y     call this function until the output stops changing:
  '0;;+           push "0", "00"
       (Æ         replace "00" with "0" in binary string
           2@¿  convert from binary to decimal

Then post a competing version!
Leaky Nun



2

PHP, 53 51 Bytes

<?=bindec(preg_replace("/0+/",0,decbin($argv[1])));

Takes an argument from the console.

Thanks to:

@manatwork replace "0" with 0


1
Mostly "0" and 0 are handled in the same way.
manatwork

@manatwork Thanks. That was a pretty obvious one I should have seen myself.
Jeroen

2

Perl, 38 + 1 (-p) = 39 bytes

$_=oct"0b".sprintf("%b",$_)=~s/0+/0/gr

Needs -p flag to run (I added -l flag to make it more readable, but it's not needed otherwise) :

perl -plE '$_=oct"0b".sprintf("%b",$_)=~s/0+/0/gr' <<< "1
9
15
13
16
17
65535
65000"

Note much to say about the code : it converts the number into binary (sprintf"%b"), then replaces blocs of zeros by just one zero, and converts the result into decimal (oct"0b".).


2

C#, 112 91 bytes

int x(int x)=>Convert.ToInt32(Rege‌​x.Replace(Convert.ToS‌​tring(x,2),"0+","0"),2);

-8 bytes thanks to TuukkaX


int f(int x){var a=Regex.Replace(Convert.ToString(x,2),"0+","0");return Convert.ToInt32(a,2);} - 94 bytes using regex. I've seen a lot of C# solutions not include System.Text.RegularExpressions so maybe it's allowed here too...?
Yytsi

int f(int x){return Convert.ToInt32(Regex.Replace(Convert.ToString(x,2),"0+","0"),2);} 86 bytes.
Yytsi

i dont know how you are counting bytes, i use this mothereff.in/byte-counter
downrep_nation

I use that page too, but it wouldn't work, so I used a different page. You should also mention the required C# version.
Yytsi

mothereff.in/byte-counter calculates 79 bytes for your current solution. I had to type the solution by hand, otherwise it would give me 91.
Yytsi

2

Java, 75

int f(Integer x){return x.valueOf(x.toString(x,2).replaceAll("0+","0"),2);}

Test program:

public class Fit {
    int f(Integer x){return x.valueOf(x.toString(x,2).replaceAll("0+","0"),2);}

    public static void main(final String... args) {
        final Fit x = new Fit();
        System.out.println(x.f(65000));
    }
}

Java 8 convert to lamda x->blah; for fewer bytes
Rohan Jhunjhunwala

int f(Integer x){return x.parseInt(x.toString(x,2).replaceAll("0+","0"));} for a couple fewer bytes
Rohan Jhunjhunwala

@RohanJhunjhunwala That's wrong, it needs to use base 2. As for the lambda, I feel that it's incomplete without the type specification.
aditsu

oh ok, the other java answer uses the same technique
Rohan Jhunjhunwala



1

PowerShell v2+, 69 bytes

[convert]::ToInt32(([convert]::ToString($args[0],2)-replace'0+',0),2)

(A shorter way to convert to/from binary in PowerShell)

Takes input $args[0], uses the .NET built-in [convert]::ToString(int,base) to convert the input integer into a binary base string. That's filtered through the -replace to strip out any runs of one-or-more-zeros to just 0. That resultant string is sent back through the other direction via [convert]::ToInt32(string,base) to turn the binary back into an integer. That integer is left on the pipeline and output is implicit.

Test Cases

PS C:\Tools\Scripts\golfing> 1,9,15,13,16,17,65535,65000|%{"$_ -> " +(.\output-fit-number.ps1 $_)}
1 -> 1
9 -> 5
15 -> 15
13 -> 13
16 -> 2
17 -> 5
65535 -> 65535
65000 -> 16250

1

Reference Implementation in S.I.L.O.S "only" 417 bytes

Golfed

readIO :
i + 1
I = i
z = 1 
n = 32
b = n
z = 1
n = b
lbla
n - 1
GOSUB p
j = i
j - p
if j b
if z c
z = 1
GOTO e
lblc
b - 1
if n a
GOTO f
lblb
z = 0
A = a
A + 1000
set A 1
i - p
lble
a + 1
if n a
lblf
q = 1000
e = q
e + b
i = 0
lbl>
d = q
d - e
if d ?
n = b
n - i
GOSUB p
g = get q
g * p
o + g
i + 1
q + 1
GOTO >
lbl?
o / 2
printInt o
GOTO z
funcp
p = 1
Z = n
lblQ
if Z C
GOTO D
lblC
Z - 1
p * 2
GOTO Q
lblD
return
lblz

Here is the reference implementation fully ungolfed. As a bonus feature it outputs the steps needed to come to an answer.

/**
*Reference Implementation in the high quality S.I.L.O.S language.
*/
readIO Enter a number to "compress"
//some declarations
i + 1
I = i
z = 1 
//the above is a flag which shows whether or not a zero was last outputted
n = 32
b = n
//maximum number of input bits
printLine Original Binary



lblbinLoop
n - 1
GOSUB pow
j = I
j - p
if j printOne
if z ENDLOOP
print 0
GOTO ENDLOOP
lblprintOne
z = 0
print 1
I - p
lblENDLOOP
if n binLoop




printLine  
printLine Binary "Compressed"


z = 1
n = b


lbltopA
n - 1
GOSUB pow
j = i
j - p
if j printAOne
if z DontPrint
z = 1
print 0
GOTO ENDLOOPA
lblDontPrint
b - 1
if n topA
GOTO endOfBin
lblprintAOne
z = 0
print 1
A = a
A + 1000
set A 1
i - p
lblENDLOOPA
a + 1
if n topA

lblendOfBin

printLine  
printLine -----------
printLine Base 10 Output
print Out Bits:
printInt b

q = 1000
e = q
e + b
i = 0
lblOutputDec
d = q
d - e
if d DONE
n = b
n - i
GOSUB pow
g = get q
g * p
o + g
i + 1
q + 1
GOTO OutputDec
lblDONE
printLine
printLine ---------
o / 2
printInt o

GOTO funcs
//function declarations must be wrapped in gotoes to avoid the interpreter from complaining (breaking)

/**
*This will store the nth power of two in the "p" variable
*/
funcpow
p = 1
Z = n
lbltop
if Z continue
GOTO end
lblcontinue
Z - 1
p * 2
GOTO top
lblend
return

lblfuncs

By request the transpilation has been deleted. Feel free to view the edit history to recover it, otherwise go to this repo for an interpreter.

Sample output for 65000

Enter a number to "compress"
65000
Original Binary
1111110111101000 
Binary "Compressed"
11111101111010 
-----------
Base 10 Output
Out Bits:14
---------
16250

4
Reference implementations should be in the challenge body, not as answers, since they are ungolfed and thus not serious contenders.
Mego

Ok, I'll golf it.
Rohan Jhunjhunwala

I didn't want to bloat up the challenge body with this @Mego
Rohan Jhunjhunwala

@TimmyD one second I'm golfing it down now
Rohan Jhunjhunwala

@Mego I have golfed it now
Rohan Jhunjhunwala

1

Pyth, 12

i:.BQ"0+"\02

Online.

  .BQ            # Convert input from base 10 to base 2
 :   "0+"\0      # Replace multiple zeroes with single zero
i          2     # Convert back from base 2 to base 10

1

Retina, 30 bytes

.+
$*1;
+`(1+)\1
$1;
1;
1
;+
0

Try it online!

And here I thought Retina would be amongst the first answers...


@randomra I'm asking the question OP for clarification
Leaky Nun

Is Retina capable of binary to decimal conversion or binary to unary conversion? I'll except either one so as to not exclude Retina
Rohan Jhunjhunwala

@RohanJhunjhunwala: Yes, it is
Business Cat

Is it possible to make this convert to unary or decimal? Ideally I would like to see decimal, but I will accept either.
Rohan Jhunjhunwala

1

Java, 152 143 138 bytes

interface C{static void main(String[]b){Integer i=0;System.out.print(i.parseInt(i.toString(i.parseInt(b[0]),2).replaceAll("0+","0"),2));}}
  • 9 bytes less thanks to @RohanJhunjhunwala. I prefer to keep it as a fully functioning program with main and the like. However, of course it can be golfed more otherwise.
  • 5 bytes less thanks to @LeakyNun's suggestions.

1
class A{public static void main(String[] a){Integer i;System.out.print(i.parseInt(i.toBinaryString(i.parseInt(a[0])).replaceAll("0+","0"),2));}} for 8 bytes of saving
Rohan Jhunjhunwala

wrap it in a lambda expression for even more saving and remove class definitions, and your set.
Rohan Jhunjhunwala

@RohanJhunjhunwala:Ah! The Integer i; part is simple and fantastic!
Master_ex

1
It works, but may produce a warning (as opposed to an error) on most sane IDE's. The thing is, you can always call static methods from a non static context, but you can never call a non-static method from a static context. While using this technique is strongly strongly discouraged in production code, it is legal java.
Rohan Jhunjhunwala

1
codegolf.stackexchange.com/questions/6671/… Is a good read to get more familiar with the lesser known (dare I say shadier) "features" of the java language.
Rohan Jhunjhunwala

1

Dyalog APL, 19 bytes

{2⊥⍵/⍨~0 0⍷⍵}2∘⊥⍣¯1

TryAPL online!

This function is really an "atop" of two functions, the first function is:

2∘⊥⍣¯1 the inverse of binary-to-decimal conversion, i.e. binary-from-decimal conversion
two 2 is bound to -to-decimal
repeat the operation negative one time ¯1 (i.e. once, but inverted)

In the second function, the above's binary result is represented by :

{2⊥⍵/⍨~0 0⍷⍵}
0 0⍷⍵ Boolean for where {0, 0} begins in ⍵
~ Boolean negation, so now we have ᴛʀᴜᴇ everywhere but at non-first zeros in zero-runs
⍵/⍨ use that to filter ⍵, so this removes our unwanted zeros
2⊥ convert binary-to-decimal


1

TSQL, 143 bytes

Not using build ins to convert from and to binary.

Golfed:

DECLARE @i INT=65000

,@ CHAR(99)=''WHILE @i>0SELECT @=REPLACE(LEFT(@i%2,1)+@,'00',0),@i/=2WHILE @>''SELECT @i+=LEFT(@,1)*POWER(2,LEN(@)-1),@=STUFF(@,1,1,'')PRINT @i

Ungolfed:

DECLARE @i INT=65000

,@ CHAR(99)=''
WHILE @i>0
  SELECT @=REPLACE(LEFT(@i%2,1)+@,'00',0),@i/=2

WHILE @>''
  SELECT @i+=LEFT(@,1)*POWER(2,LEN(@)-1),@=STUFF(@,1,1,'')

PRINT @i

Fiddle


+1 for not using built ins. My S.I.L.O.S answer (reference implementation) does the same, but it got downvoted as people didn't think it was a serious competitor. Is the new line significant?
Rohan Jhunjhunwala

@RohanJhunjhunwala the new line is not significant. I am counting the characters of the code after the input variable has been defined and assigned a value.
t-clausen.dk

ok amkes sense -
Rohan Jhunjhunwala

@RohanJhunjhunwala I think it is cool that you use an unconversial language to solve Codegolf questions. It does seem you have unnecessary code to add extra information - probably only in your ungolfed version though. You should always try to provide the shortest code possible, cutting corners and abusing language querks(within the scope of the question). If possible you should provide a fiddle, so muggles me can test it
t-clausen.dk

The ungolfed version contains unnecessary code, but the golfed version contains no additional code. I can transpiler it into java if you want me to test it.
Rohan Jhunjhunwala

1

CJam, 16

q~2b1+0a%0a*);2b

Try it online

It's quite long due to lack of regex.

Explanation:

q~     read and evaluate the input number
2b     convert to base 2 (array of 1s and 0s)
1+     append a 1 to deal with trailing zeros
0a%    split by [0], dropping empty pieces; only chunks of 1s are left
0a*    join by [0]
);     discard the 1 we appended before
2b     convert back from base 2

1

Java, 64 bytes

i->{return i.parseInt(i.toString(i,2).replaceAll("0+","0"),2);};

Test Program

public static void main(String[] args) {
    Function<Integer, Integer> function = i -> {
        return i.parseInt(i.toString(i, 2).replaceAll("0+", "0"), 2);
    };

    System.out.println(function.apply(1)); // 1
    System.out.println(function.apply(9)); // 5
    System.out.println(function.apply(15)); // 15
    System.out.println(function.apply(13)); // 13
    System.out.println(function.apply(16)); // 2
    System.out.println(function.apply(17)); // 5
    System.out.println(function.apply(65535)); // 65535
}

1

CJam, 23 bytes

ri2be`{_:g:>{:g}&}%e~2b

Try it online!

Explanation

ri          e# Read input as an integer
2b          e# Convert to binary
e`          e# Run-length encoding. Gives a nested (2D) array with run-lengths 
            e# and binary digits
{           e# This block is mapped over the outer array, i.e. is applied to
            e# each inner array
   _        e#   Duplicate the inner array
  :g        e#   Signum of each element of inner array
  :>        e#   This gives true if second element (digit) is false and first
            e#   element (run-length) is not zero. If so, we need to set that
            e#   run-length to 1
  {:g}&     e#   If that's the case, apply signum to original copy of inner
            e#   array, to make run-length 1
}%          e# End block which is mapped over the outer array
e~          e# Run-length decoding
2b          e# Convert from binary. Implicitly display

1

Ruby, 37 35 bytes

Saved two bytes thanks to manatwork.

->a{a.to_s(2).gsub(/0+/,?0).to_i 2}

The naive approach. (:


Regarding "0", see the 2nd point in sepp2k's tip. Regarding .to_i(2), where there is no ambiguity on where a parameter belongs, the parentheses are optional.
manatwork

1

C, 37 bytes

f(x){return x?f(x/2)<<!!(x%4)|x&1:0;}
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.