确定一个数字是否可以被13整除(不使用13本身)。


31

如果您选择接受它,那么您面临的挑战是创建一个函数或程序,如果给定数字可被13整除,则输出“是”,否则将输出“否”。

规则:
-不允许在任何地方使用数字13。
-也没有针对13的cop-out同义词(例如使用15-2)。
-如果不使用模数,将获得奖励积分,如果不使用除法,则将获得额外奖励。

评分:
-您的分数将是代码中的字节数(包括空格)乘以您的奖金。
-如果您不使用模数,则该奖励为0.90;如果您不使用除法,则该奖金为0.90。
-如果您都不使用,则该奖励为0.80。
-分数越低越好。

输入将始终是大于0且小于2 ^ 32的整数。
您的输出应该是简单的“是”或“否”。

澄清:
-可以采用一些绕行方法来生成数字13。不允许使用简单的算术同义词,例如(10 + 3)。
- 如果给定的数字可被13整除,则函数或程序必须按字面输出 “是”或“否”。-
与往常一样,建议(但不是必须)明智的解决方案。


'true'或'false'是有效输出吗?
开拓者

8
JavaScript(27个字符)function f(n){return "yes"}。这将为所有可以除以13的数字返回“是”
ajax333221

5
始终会在以下两种情况之一中导致“(不包括空白)”:程序将其内容编码为空白,或者是用空白语言编写的程序(编程语言)
JiminP 2012年

4
Using some roundabout method of generating the number 13 for use is acceptable.您如何确定“回旋处足够”?
Cruncher 2014年

3
@Rusher说实话,我没有注意到它已经2岁了,它最近才活跃起来。至于你的建议,我宁愿不要忍者变化非OP 2页答案..的问题
排排坐

Answers:



19

ASM-WinXP命令外壳上的16位x86

可执行文件-55字节* 0.8 = 44

来源-288个字符* 0.8 = 230.4

数字13甚至没有出现在组合的.com文件中。

使用A86组装。

    mov si,82h
    xor ax,ax
    xor cx,cx
a:  imul cx,10
    add cx,ax
    lodsb
    sub al,48
    jnc a
    inc cx
h:  mov dl,a and 255
c:  loop g
    sub dl,a and 255
    jz e
    mov dl,4
e:  add dl,k and 255
    mov dh,1
    mov ah,9
    int 21h
    ret
g:  inc dl
    cmp dl,c and 255
    jne c
    jmp h
k:  db 'yes$no$'

我知道此解决方案很聪明,但是由于这是代码问题,我们是否应该赞成最短的解决方案而不是最聪明的解决方案?
mellamokb '02 -2-28

21
@mellamokb:根据我在meta上阅读的内容,有人认为投票是对聪明/不寻常解决方案的赞赏。如果我们仅对最短答案进行投票,那么投票毫无意义。我猜想,“滴答声”使用最短的代码作为最终荣誉的标记。再说一次,golfscript中的简单解决方案总是比C中的真正聪明解决方案小-那么谁值得投票?最后,投票并不是那么重要,这是关于获得乐趣。
Skizz

1
规则:The input will always be an integer greater than 0 and less than 2^32。您不能使用16bit
Fabricio 2014年

@Fabricio:所有16位数字均小于2 ^ 32。:-)
Skizz

大声笑..你是正确的。但您无法处理2 ^ 32-1 = p
Fabricio 2014年

17

Python 3.x:54 * 0.8 = 43.2

长度为13的字符串可能很适合,但在这里行得通:

print('no' if any((' ' * int(input())).split('             ')) else 'yes')

它的工作方式是构建一个由n个空格组成的字符串(定界符的选择是任意的,但出于显而易见的原因,我选择了空格),然后拆分13个空格的子字符串,直到剩下包含n%13个空格的字符串为止。


4
+1。我喜欢以13个字符分隔的空格。将其移至Python 2并使用我的回答中的一项技术将其得分降至35.2:print 'yneos'[any((' ' * input()).split(' '))::2]
Steven Rumbalski 2012年

我要说的是:您可以替换' '' '*6+' '以节省5个字符-但后来我发现空格根本不算在内...
kratenko

15

GolfScript,32个字符

~){.14base{+}*.@<}do('no''yes'if

我想尝试与众不同的方法,因此我的解决方案通过将数字重复转换为以14为基数来计算数字的以14为底的数字根并求和直到结果不再变小。这与计算余数模13基本相同,除了结果将在1到13而不是0到12的范围内。

由于不使用数字13本身(或某些类似12 + 1的la脚解决方法)很难检查数字根是否等于13,因此我实际要做的是在循环之前将输入数字加1,然后再减少结果。这样,被13整除的数字的结果实际上将为零,这很容易检查。

这是程序的注释版本:

~              # evaluate the input, turning it from a string to a number
)              # increment by one
{              # start of do-loop 
    .          # make a copy of the previous number, so we can tell when we're done
    14 base    # convert the number to base 14
    { + } *    # sum the digits
    . @ <      # check if the new number is less than the previous number...
} do           # ...and repeat the loop if so
(              # decrement the result by one
'no' 'yes' if  # output 'no' if the result is non-zero, 'yes' if it's zero

该程序实际上将处理任何非负整数输入,因为GolfScript使用bignum算法。当然,非常大的输入可能会消耗过多的时间和/或内存。

该代码虽然直接使用GolfScipt的基本转换运算符,但它并没有直接使用模或除法,几乎可以肯定它在内部进行了除法和余数运算。我将把它留给GigaWatt来决定,这是否使我有资格获得奖金。


如果每个人都这么好地评论他们的golfscript代码。荣誉
skibrianski 2014年

13

C,68 * 0.8 = 54.4

经过24个回答,还没有人想出这个明显的算法:

f(x){puts("no\0yes"+3*((x*330382100LL>>32)-(~-x*330382100LL>>32)));}

我在等待有人做一个整数倒数乘法。它不仅是应对挑战的理想解决方案,而且就性能优化而言,它本身就是一种有用的技术。
Sir_Lagsalot'2

即使它不是非常标准,这仍然有效吗?
oldrinb 2012年

1
@oldrinb,我认为该问题不要求符合标准。通常,严格的标准合规性在代码高尔夫球中非常令人讨厌。
ugoren 2012年

您能解释一下为什么行得通吗?
Vedaad Shakib

@ user2767189,这是一种称为“倒数乘法”的技术-基本上是一种通过乘以(2 ^ K / X)来实现X除法的方法。在这种情况下,X为13,而330382100 * 13几乎恰好是2 ^ 32。
ugoren 2015年

11

JavaScript (27.9)

Current version (31 characters * 0.90 bonus = 27.9).

alert(prompt()*2%26?'no':'yes')

Demo: http://jsfiddle.net/9GQ9m/2/

Edit 1: Forgo second bonus by using modulus to lower score considerably and avoid for loop. Also eliminate ~~ and save two chars (thanks @copy).


Older version (48 characters * 0.80 bonus = 38.4)

for(n=~~prompt()*2;n-=26>0;);alert(n?'no':'yes')​

Multiply everything by two and use 26 instead... didn't see that coming.
Mr. Llama

You can omit the ~~ assuming valid input; otherwise prompt()<<1 will work too.
copy

Although I will admit it technically doesn't reach the limit of 2^32 anymore using this method..
mellamokb

1
In fact it does work beyond 2^32 since you dropped any bitwise operators now.
copy

3
This is still using an arithmetic quickie to determine divisibility by 13, and there was a rule saying no arithmetic cop outs...
WallyWest

7

BrainFuck

Score: 200 * 0.8 = 160

>++++++[>++++++++<-]>>,[<[-<+>>-<]<[->+<]>>>[->++++++++++<]>[-<+>]<<[->+<],]++++
+++++++++>[>+<-<-[>>>]>>[[-<<+>>]>>>]<<<<]>[<<<[-<++>]<++++++++++++++.+.>]<<[[-<
++++++<++++++++>>]<-----.<---.>------.>]

Reads froms stdin. Probably not the most clever solution, but getting anything that works in BF is nice. It's quite compact though.


Any explanation on how it works? It seems like by default BrainFuck would get the full 0.8 bonus because it simply doesn't have division or modulus.
Mr. Llama

@GigaWatt it calculates the modulus.
copy

1
Aye, but what I meant was that it doesn't use the modulus operator (because it doesn't have one). Therefore it'll always get the bonus for not using it. Also, nice bio pic.
Mr. Llama

@GigaWatt I didn't disagree with you, just answered your question.
copy

7

Scala (38 * 0.9 = 34.2)

Similar to 0xD(hex) or 015(oct).

ASCII value of CR is 13.

def t(n:Int)=if(n%'\r'==0)"yes"else"no"

1
I wondered how long it'd be before I saw someone exploit ascii values.
Mr. Llama

1
Can you add the score to your post please? Should be 38 * 0.9 = 34.2.
mellamokb

5

Haskell, 28 * 0.8 = 22.4

f x|gcd 26x>2="yes"|1<3="no"

5

Python:

f=lambda n:1==pow(8,n,79)

E.g.

[i for i in range(100) if f(i)]

gives

[0, 13, 26, 39, 52, 65, 78, 91]

1
now this one I like. however there needs to be a yes/no according to the challenge criteria, and you should post your score (25*.08 = 20)
Blazer

f=lambda n:pow(8,n,79)-1 and "no" or "yes" fixes it, 43*0.8=34.4
ugoren

4

C, 54.4 == 68 * .8   80 * .8

char*f(c){char*s=" yes\0\rno";while(c&&*s++);return c>0?f(c-*s):++s;}

Nice use of \r - I thought it's only good for Windows support. But why c>0 when c would do?
ugoren

@ugoren: it wouldn't do, think about it.
ceased to turn counterclockwis

You're right, I got confused somehow. I was thinking about numbers above 2^31, where >0 is no good. But instead of noticing that your function doesn't support them, I thought == is good.
ugoren

4

ECMAScript 6, 25 × 0.9 = 22.5

Yeah, it's a boring way of getting 13.

n => n % '             '.length ? 'no' : 'yes'

i was trying to figure out how your score was so low, then i realized the genius in using whitespace for your number... lol
mellamokb

1
+1 for abusing the rules. If I stated them, it would be "not counting REMOVABLE whitespace". So is anyone going to give us a 0 byte solution?
ugoren


3

APL ((21 - 1) × 0.8 = 16)

'yes' 'no'[1=⎕∨⌊⍟9*6]

⎕IO should be set to 0 for this to work properly in Dyalog APL. To generate 13, we take the floor () of the natural logarithm () of 9 to the power of 6 (9*6). After that, we find the GCD () of our input () and 13, and we then test if that equals 1. This is used to index ([...]) the vector of answers.

If anyone wants to be pedantic about the mention of bytes in the scoring specification, the score for the UTF-8 encoded version of this is (29 - 1) × 0.8 = 22.4. :)


1
I so want to be pedantic about bytes.
Steven Rumbalski

1
Ohhhhhhhh snap you di-int.
Dillon Cower

3

C, 88

Fibonacci trick.

f(n){return n<2?n:f(n-1)+f(n-2);}main(x){printf("%s",x%f(7)?"No":"Yes",scanf("%d",&x));}

2
You're using 13 via f(7)... That's kinda bending the rules a bit...
WallyWest

3

Perl - 44 × 0.8 = 35.2

#!perl -p
map$_+=4*chop,($_)x10;$_=chop^$_*3?'no':yes

Counting the shebang as one byte.

I'm a bit late to the game, but I thought I'd share the algorithm, as no other posts to this point have used it.

This works under the observation that if n is divisible by 13, then ⌊n/10⌋+n%10*4 is also divisible by 13. The values 13, 26 and 39 cycle onto themselves. All other multiples of 13 will eventually reach one of these values in no more than log10 n iterations.


In Other Bases

Admittedly, chop is a bit of a cop-out. With a base 10 representation, it's equivalent to divmod. But the algorithm works prefectly well in other bases, for example base 4, or 8.

Python style pseudo-code of the above algorithm (base 10):

def div13(n):
    while n > 40:
        q, r = n // 10, n % 10
        n = q + 4*r
    return n in [13, 26, 39]

In base 2:

def div13(n):
    while n > 40:
        q, r = n >> 1, n & 1
        n = q + 7*r
    return n in [13, 26, 39]

In base 4:

def div13(n):
    while n > 40:
        q, r = n >> 2, n & 3
        n = q + 10*r
    return n in [13, 26, 39]

In base 8:

def div13(n):
    while n > 40:
        q, r = n >> 3, n & 7
        n = q + 5*r
    return n in [13, 26, 39]

etc. Any base smaller than 13 works equally well.


2

Javascript: 59*0.8 = 47.2 (?)

fiddle:

function r(n){
  for(c=0;n>c;n-=12,c++);
  return n==c?'yes':'no';
}

Including mellamokb's improvement (57*0.8 = 45.6):

function r(n){
  for(c=0;n>c;n-=12,c++);
  return n-c?'no':'yes'
}

1
You can save two chars by changing return to return n-c?'no':'yes' and omitting the second semicolon.
mellamokb

@mellamokb Good catch. Could probably improve further by writing it in Ruby, or something that allows more compact function definitions.
Supr

There is also an accepted standard on CG to use prompt for input and alert for output, which makes the program interactive and saves a few chars.
mellamokb

2

Perl: (51-4 spaces)*0.9 = 42.3

say+<>%(scalar reverse int 40*atan2 1,1)?'no':'yes'

40*atan2(1,1) -> 31.41592 (PI*10)


2

Perl (19.8)

21 bytes * .9

say2*<>%26?"no":"yes"

note: My first Perl program ever. Weakly typed is good for golf i guess.


I've found that a good way to measure your knowledge of a language is to try and golf in it. Usually requires knowing edge cases. Also, your score is actually 23 * 0.90 (whitespace doesn't count).
Mr. Llama

Thought I had accounted for the whitespace. Fixed now. Thanks for pointing that out.
Steven Rumbalski

Wow. No love for Perl. Can't say I like it either.
Steven Rumbalski

2

in C (K&R): 47 * 0.8 = 37.6

f(i){for(;i>0;i-=__LINE__);puts(i?"no":"yes");}

EDIT1: okay removed all dependencies on external functions, the above will work as long as you put this line on the 13th line of the file! :) If __LINE__ is okay to be replaced by say 0xd then can save a further 5 characters (score: 33.6)


7
If this needs to be on 13th line, you need to add 12 newlines to your code, and therefore, to your score: it becomes 59 * 0.8 = 47.2
Vereos


2

JavaScript (108 less 0 for whitespace) => 108, x 0.8 (no modulus, no division) = 86.4

b=b=>{a=z,a=a+"";return+a.slice(0,-1)+4*+a.slice(-1)};z=prompt();for(i=99;i--;)z=b();alert(b()-z?"no":"yes")

This method uses the following algorithm: 1. Take the last digit, multiply it by four, add it to the rest of the truncated number. 2. Repeat step 1 for 99 iterations... 3. Test it one more time using step 1, if the resulting number is itself, you've found a multiple of 13.

Previous update, removed var, and reversed logic at the alert to remove more chars by using subtraction-false conditional.

Technically, the end result is that you'll eventually reach a two digit number like 13, 26, or 39 which when run through step 1 again will give 13, 26, or 39 respectively. So testing for iteration 100 being the same will confirm the divisibility.


2

Cheddar, 20 bytes (noncompeting)

Score is 20 * 0.9 = 18

n->n*2%26?'no':'yes'

A straightforward answer.


2

Common Lisp (71 bytes * 0.8) = 56.8

Simple recursion, really.

(defun w(x)(if(> x 14)(w(- x 13))(if(> 14 x 12)(print'yes)(print'no))))

Ungolfed:

(defun w (x)
  (if (> x 14)
      (w (- x 13))
      (if (> 14 x 12)
          (print 'yes)
          (print 'no))))

2

Ruby (50 48 * 0.9 = 43.2)

Smart way to use eval

eval x="p gets.to_i*3%x.length == 0? 'yes':'no'"

1

D 56 chars .80 bonus = 44.8

bool d(double i){
    return modf(i*0,0769230769,i)<1e-3;
}

this might have been a cop-out with using 1/13 and a double can store any 32 bit number exactly

edit: this works by multiplying with 1/13 and checking the fractional part if it's different from 0 (allowing for rounding errors) or in other words it check the fractional part of i/13


doesn't modf count as using modulus?
Blazer

@Blazer not really it takes the fractional part of the first argument and returns it while storing the integral part in the second arg
ratchet freak

Just a note: the result (yes/no) has to actually be output. Also, I'm somewhat curious as how this solution works. An explanation would be much appreciated!
Mr. Llama

1

Python 2.7

(20 - 1 whitespace) * 0.9 (no division) = 17.1

print input()%015==0

yes/no instead of true/false: 31 * 0.9 (no division) = 27.9

print'yneos'[input()%015!=0::2]

takes advantage of python's int to convert other bases from strings into base 10 integers. you can see in both versions they use a different (yet same character length) base

edit: 1 char save in yes/no version

edit2: another 2 chars shaved!

edit3: thanks again to comments! even more characters shaved off by using python's builtin octal representations (015 == 13...) instead of int's base translation


3
I see a cop-out with the different bases
ratchet freak

14 in base 9? I should have seen that coming.
Mr. Llama

1
print['no','yes'][input()%int('d',14)==0
Steven Rumbalski

as far as I saw, a cop-out was defined as being something like 14-1 or 26/2. I just took creative liberty to represent 13
Blazer

@StevenRumbalski thanks for the 1 char save :P
Blazer

1

Perl, 95 * 0.8 = 76

$_=<>;
while($_>0){
$q=7*chop;
$d=3*($m=chop$q);
chop$d;
$_-=$d+$m}
if($_){print"no"}
else{print"yes"}

The line breaks were added for clarity. I could have probably made this answer a lot shorter, but I feel that this answer represents a unique way of approaching the problem.


1

Python - score 27.9

(31 characters * 0.90) -- forgoes some bonus for shorter code.

print'yneos'[2*input()%26>0::2]

older version: (47 characters * 0.80) -- complete rip-off of mellamokb's Javascript answer, but in Python.

n=2*input()
while n>0:n-=26
print'yneos'[n<0::2]

older version: (60 characters * 0.80)

n=input()
while n>12:
 for _ in'x'*12+'!':n-=1
print'yneos'[n>0::2]

older version: (105 characters * 0.80)

n=abs(input())
while n>12:n=abs(sum(int(x)*y for x,y in zip(`n`[::-1],n*(1,-3,-4,-1,3,4))))
print'yneos'[n>0::2]

Hmm, this is a nifty method. That 1,-3,-4 pattern is similar to what I saw on wikipedia. Still cool to see it in code.
Mr. Llama

@GigaWatt: That's where I got it. The other pattern (1,10,9,12,3,4) would save 1 character but would not resolve to a value less than 13.
Steven Rumbalski

1

In Q:

d:{$[0=x mod "I"$((string 6h$"q")[1 2]);`yes;`no]}
50*.9=45

Welcome to CodeGolf.SE. You should put your code in a codeblock, and which point you can use backticks where you mean backticks as they no longer have formatting meaning. I've done the first part for you, please check it and fix any errata I've introduced.
dmckee

1

Right Linear Grammar - ∞ points

S->ε
S->1A
S->0S
S->9I
S->3C
S->5E
S->4D
S->2B
S->7G
S->6F
S->8H
F->3K
K->0F
A->2L
K->1G
A->5B
A->0J
B->7A
J->5A
G->6K
G->8S
H->9K
F->5S
K->2H
I->6E
I->5D
J->4S
D->8I
B->6S
K->9B
F->6A
G->9A
K->6L
K->4J
C->1E
L->8K
E->5C
B->4K
C->0D
J->2K
D->2C
A->9F
J->7C
C->6J
C->8L
E->0K
L->0C
B->9C
E->2S
L->6I
I->0L
J->0I
B->2I
I->3B
H->1C
I->7F
C->4H
F->1I
G->4I
I->0G
C->3G
F->8C
D->0A
E->3A
I->9H
A->7D
C->2F
H->7I
A->8E
F->9D
E->8F
A->6C
D->6G
G->0E
D->5F
E->9G
H->2D
D->7H
H->3E
I->2A
K->3I
C->9S
C->7K
E->4B
D->1B
L->1D
J->9E
I->1S
E->1L
J->8D
D->9J
L->2E
J->3L
B->5L
B->8B
L->7J
L->9L
G->1F
A->4A
K->5K
B->3J
H->6H
E->7E
J->1J
D->4E
G->2G
J->6B
D->3D
E->6D
H->4F
I->4C
C->5I
F->0H
H->5G
K->7S
G->3H
L->5H
H->8J
A->3S
H->0B
B->1H
G->7L
K->8A
F->2J
F->7B
L->4G
F->4L
A->1K
B->0G
G->5J
L->3F

Then depending on how you choose to 'run' it, it will output 'yes' or 'no'.

Not a serious entry, just some fun ;)

EDIT: Perhaps I should explain a bit.

A grammar is a set of rules (productions) which define a language. A language can be thought of as all of the possible strings formed by an alphabet, that conform to the rules of it's grammar.

Here the alphabet is the set of all decimal digits. The grammar's rules are that all strings must form decimal integers that are divisible by 13.

We can use the grammar above to test whether a string belongs to our language.

The rules of the grammar contain terminal symbols (which are elements in the language) as well as non-terminal symbols which are replaced recursively.

It's easier to explain what's going on with an example:

Lets say for example that the string we are testing is 71955.

There is always a start symbol (which is non-terminal), in the case of the grammar above this is 'S'. At this point we have not read any characters from our string:

current pattern                    symbol read
S                                  ε

Now, we read the first symbol in our string which is '7', then we look for a rule in the grammar which has any of the non-terminals in our current pattern in the left hand side of the '->' and that has our symbol in the right hand side of the '->'. Luckily there is one (S->7G), so we replace the non-terminal symbols in our current pattern with the right hand side of the new rule:

current pattern                    symbol read
7G                                 7

Now we have the non-terminal 'G' in our pattern, and the next symbol to be read is '1', So we look for a rule in our grammar that begins with 'G->1". We find there is one (G->1F), so we replace the non terminal with the RHS of our new rule:

current pattern                    symbol read
71F                                1

Keep repeating this process:

Next rule: F->9D

current pattern                    symbol read
719D                               9

Next rule: D->5F

current pattern                    symbol read
7195F                              5

Next rule: F->5S

current pattern                    symbol read
71955S                             5

At this point we have no more symbols in our string, but we have another non-terminal symbol in there. We see from the first rule in the grammar that we can replace 'S' with the empty string (ε): S->ε

Doing so gives us the current patter: 71955ε which is the equivalent to 71955.

We have read all of the symbols in our string, and the pattern contains no non-terminal symbols. Which means that the string belongs to the language and therefore 71955 is in fact divisible by 13.

I.e. the goal is to have pattern = string. If you are left with any non-terminal symbols, after reading all of the symbols in your string, the string doesnt belong to the language. Likewise, if you still have more symbols in your string to read, but there are no rules in the grammar allowing you to go forward, then the string does not belong to the language.


I'm... not even sure what I'm looking at here.
Mr. Llama

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.