바운스 모듈로 두 숫자


12

모듈로 연산의 그래프 ( y=xmodk )는 다음과 같습니다.

모듈로 함수의 그래프

이것은 "래핑"동작을 만들 수 있기 때문에 매우 유용한 기능입니다. 그러나 두 벽 사이에 "튀는"모양을 만드는 데 사용하려는 경우 매우 번거 롭습니다. "bounce"함수 ( y=bounce(x,k) ) 의 그래프는 다음과 같습니다.

"바운스 모듈로"기능의 그래프

기간 의 그래프의 IS . 의 그래프주기 는 . 왜냐하면 단위 는 위쪽으로 이동 한 다음 다른 단위에서는 아래쪽으로 이동 하기 시작한 지점으로 돌아갑니다. 두 함수 모두에서 의 최소값 은 0이고 최대 값은 (실제로 입력이 통합 된 계수 함수의 경우 ). 또한 두 함수 모두 값 입니다.k y = 바운스 ( x , k ) 2 k k k y k k 1 x = 0y=xmodkky=bounce(x,k)2kkkykk1x=0

도전

정수 와 양의 정수 주어지면 의 정수 또는 부동 소수점 근사값을 반환합니다 .k y = 바운스 ( x , k )xky=bounce(x,k)

이것은 이므로 가장 짧은 유효한 제출 (바이트로 계산)이 이깁니다.

테스트 사례

  x,  k -> bounce(x, k)
  0, 14 ->            0
  3,  7 ->            3
 14, 14 ->           14
 15, 14 ->           13
-13, 14 ->           13 (12.999997 etc would be an acceptable answer)
-14, 14 ->           14
191,  8 ->            1
192,  8 ->            0

A에 대한 보너스 포인트 푸리에 의 접근 방식을 기반 푸리에 .


" 두 기능 모두에서 x의 최소값은 0이고 최대 값은 k입니다. "
피터 테일러

@PeterTaylor Whoops. 결과를 의미합니다.
Esolanging 과일

1
죄송합니다. 이미 그렇게 생각했습니다. 여전히 잘못되었습니다. k % k = 0
피터 테일러

@PeterTaylor 오, 나는 당신의 질문을 이해합니다. 나는 원래 부동 소수점을 염두에두고 이것을 디자인 한 후 int로 바꿨습니다. 편집합니다.
Esolanging 과일

1
@PeterTaylor 인수가 부동이면 최대 값은 임의로에 가까운 숫자 k입니다.
Esolanging 과일

답변:


7

x86-64 기계 코드, 18 바이트

97
99
31 D0
29 D0
99
F7 FE
29 D6
A8 01
0F 45 D6
92
C3 

이 코드는를 계산하는 x86-64 기계 언어의 함수를 정의합니다 bounce(x, k. 다음과 같은 시스템 V AMD64 호출 규칙 GNU / 유닉스 시스템에서 사용의 x매개 변수는에 전달 EDI그동안, 레지스터 k매개 변수가 전달되는 ESI레지스터. 모든 x86 호출 규칙과 마찬가지로 결과는 EAX레지스터에 반환됩니다 .

C에서 이것을 호출하려면 다음과 같이 프로토 타입을 작성하십시오.

int Bounce(int x, int k);

온라인으로 사용해보십시오!

ungolfed 어셈블리 니모닉 :

; Take absolute value of input 'x' (passed in EDI register).
; (Compensates for the fact that IDIV on x86 returns a remainder with the dividend's sign,
; whereas we want 'modulo' behavior---the result should be positive.)
xchg   eax, edi      ; swap EDI and EAX (put 'x' in EAX)
cdq                  ; sign-extend EAX to EDX:EAX, effectively putting sign bit in EDX
xor    eax, edx      ; EAX ^= EDX
sub    eax, edx      ; EAX -= EDX

; Divide EDX:EAX by 'k' (passed in ESI register).
; The quotient will be in EAX, and the remainder will be in EDX.
; (We know that EAX is positive here, so we'd normally just zero EDX before division,
; but XOR is 2 bytes whereas CDQ is 1 byte, so it wins out.)
cdq
idiv   esi

; Pre-emptively subtract the remainder (EDX) from 'k' (ESI),
; leaving result in ESI. We'll either use this below, or ignore it.
sub    esi, edx

; Test the LSB of the quotient to see if it is an even number (i.e., divisible by 2).
; If not (quotient is odd), then we want to use ESI, so put it in EDX.
; Otherwise (quotient is even), leave EDX alone.
test   al, 1
cmovnz edx, esi

; Finally, swap EDX and EAX to get the return value in EAX.
xchg   eax, edx
ret

첫 번째 섹션 (절대 값을 취함)은 동일하게 작성 될 수 있습니다.

; Alternative implementation of absolute value
xchg    eax, edi
neg     eax
cmovl   eax, edi

정확히 같은 바이트 수입니다 (6). 조건부 이동이 느린 특정 인텔 칩을 제외하고는 성능이 약간 빨라야 합니다.

XCHG물론, MOV코드 골프 를 제외 하고는 상대적으로 느리고 선호되지 않습니다 (피연산자 중 하나가 누산기 인 경우 전자는 1 바이트이지만 레지스터 레지스터 MOV는 항상 2 바이트입니다).


6

젤리 , 3 바이트

æ%A

온라인으로 사용해보십시오!

내장 ftw.

설명

æ%여기에 유용한 내장 기능이 있습니다. 설명 방법을 모르므로 일부 입력에 대한 출력 만 제공합니다.

대로 x에서 진행 0무한대, xæ%4간다 0,1,2,3,4,(-3,-2,-1,0,1,2,3,4,)괄호 안의 부분은 두 가지 무한대로 반복된다.




3

루비, 40 바이트 32 바이트

b=->(x,k){(x/k+1)%2>0?x%k:k-x%k}

온라인으로 사용해보십시오!

설명

안녕하세요,이 사이트의 첫 답변입니다! 이 코드는 관찰에 기초하는 반송 기능 모듈로 동작합니다 정확히 같은 경우 ( N -1) K <= X < NK n은 홀수 및 역전 모듈러스 조작과 같이 동작 n은 짝수이다. x / k(x/k+1) 보다 큰 가장 작은 정수 입니다 ( x / k +1은 정수로 내림 됨). 따라서 위에서 언급 한 n을 찾습니다 . n 이 홀수인지 짝수인지 확인합니다 . 경우 n이 2> 0을 개조 한 후 N 홀수이다. 만약 n(x/k+1)%2>0mod 2 = 0이면 n 은 짝수입니다. 경우 n이 홀수 후 반송 함수는 동일해야 X 개조 K . 경우 n이 짝수, 반송 기능 반대이어야 동일 케이 - X 개조 K . 전체 표현식 (x/k+1)%2>0?x%k:k-x%kn을 찾은 다음 x mod k 가 홀수이면 실행하고, 그렇지 않으면 k - x mod k를 실행 합니다.

답변은 Cyoce 의 제안에 따라 개선되었습니다 .


이것을 람다로 변환 할 수 있습니다. 대신 def b(x,k) ... end사용->x,k{...}
Cyoce

그리고 정수를 다루기 .to_i때문에 필요하지 않습니다.
Cyoce



1

J, 25 바이트

힌트:

이것은 래더 번호의 규칙적인 모듈로입니다. 예를 들어 5의 경우 :0 1 2 3 4 5 4 3 2 1

다음은 J의 (아직 잘 구현되지 않은) 솔루션입니다. 내일을 개선하려고 노력할 것입니다.

[ ((|~ #) { ]) (i.@>:,}:@i.@-) @ ]

압축 : [((|~#){])(i.@>:,}:@i.@-)@]

압축 2 : [((|~#){])(<:|.|@}.@i:)@]

온라인으로 사용해보십시오!


나는 i:여기에 사용될 수 있다고 생각 하지만 아직 해결책을 시도하지 않았습니다
Conor O'Brien

@ ConorO'Brien은 compression2 버전을 확인하고를 사용하여 몇 바이트를 절약합니다 i:. 기본 업데이트를 업데이트하고 설명을 제공 할 시간이 없었습니다. 나는 전문가가 적어도 다른 4 또는 5 바이트를 깎을 수있을 것으로 기대합니다 ...
Jonah

((|~#){])]-|@}:@i:18 바이트 동안
마일

@ 마일 아름다운, tyvm
Jonah

1

QBIC , 25 30 27 바이트

g=abs(:%:)~a'\`b%2|?b-g\?g

약간의 구조 조정을 했습니까?

설명

g=abs(   )  let g be the absolute value of 
       %    the (regular) modulo between
      : :   input a read from cmd line, and input b read from cmd line
~a \ b%2    IF the int division of A and B mod 2 (ie parity test) yields ODD
  ' `         (int divisions need to be passed to QBasic as code literals, or ELSE...)
|?b-g       THEN print bouncy mod
\?g         ELSE print regular mod

QBIC은 다른 기본 구현과 다른 MOD 작업에 대해 다른 기능을 수행합니까? 다른 기본은 배당금과 같은 부호를 가진 MOD를 반환합니다. 그것은 x-13이고 k14 일 때 실패 할 것 입니다.
Cody Grey

@CodyGray Nope, 그것은 -13을 주었다. 지금 수정했습니다.
steenbergh

abs두 시간 이 필요하지 않습니까?
Neil

@ Neil 당신은 그것에 대한 테스트 케이스가 있습니까?
steenbergh

@ Neil nvm, 나는 모든 것을 재구성하여 고쳤습니다.
steenbergh

1

C89, 40 바이트

t;f(x,k){t=abs(x%k);return x/k%2?k-t:t;}

의 AC 포트 내 86 기계 코드의 대답은 ,이 함수 정의 f, 그 계산 매개 변수에 대한 바운스 모듈 xk.

C89의 implicit-int 규칙을 사용하므로 매개 변수, 전역 변수 t및 함수의 반환 값이 모두 암시 적으로 유형 int입니다. 전역 변수 t는 임시 값을 유지하는 데 사용되며 조건부 연산자의 양쪽에서 계산을 반복하는 것과 비교하여 바이트를 절약합니다.

abs기능 (절대 값)가 제공됩니다 <stdlib.h>헤더, 그러나 우리는 여기서 다시, (함수가 암시 적으로 선언하고 반환에 가정 C89의 암시-INT 규칙에 감사를 포함 할 필요가 없습니다 int).

온라인으로 사용해보십시오!

언 골프 버전 :

#include <stdlib.h>

int Bounce(int x, int k)
{
    int mod = abs(x % k);
    return (x/k % 2) ? k-mod : mod;
}

필자가 직접 조정 한 머신 코드 에 비추어 이것을 보면 컴파일러는 실제로 이것에 대해 꽤 좋은 출력생성 합니다. 내 말은, 그들은해야합니다; 최적화하는 것은 매우 간단한 기능입니다! 내가 한 GCC의 x86-64에 최적화에있는 작은 버그 발견 은 호기심 생산하는 곳,하지만, 더 큰 코드를 사용하면 크기에 대한 최적화와 그것을 말할 때 작은 당신이 최적화로 말할 때 코드 속도 .


m;f(x,k){m=abs(x%k);x=x/k%2?k-m:m;}is
shorter

x86 대상의 GCC 코드 생성기 문제로 인해 잘못 정의 된 특정 상황 이외의 값인 @cows를 실제로 반환하지는 않습니다. 사람들이 여기에서 사용하는 템플릿이지만, 올바른 답변이되는 스택에서 임의의 쓰레기를 가져 오는 것 이상으로는 효과가 없습니다.
코디 그레이

1

하스켈, 37 바이트

온라인으로 사용해보십시오!

(!)=mod;x#k|odd$x`div`k=k-x!k|1<2=x!k

사용법 : 하스켈은 마치 당신이 같은 것을 사용하는 것처럼 해석하기 때문에 음이 아닌 왼쪽 인자에 대해, 부정적인 왼쪽 인자에 대해
호출하십시오 . TIO 링크는 단순히 두 개의 명령 줄 인수를 사용합니다.15#14(-13)#14-13#14-(13#14)ghci

설명 :
먼저 이진 접두사 연산자 !가와 동일하도록 재정의합니다 mod. Haskell 's는 mod항상 음수가 아닌 값을 출력하므로 abs여기에 다른 솔루션이 필요하지 않습니다 . 그런 다음 x/k(정수 나누기)가 홀수 인지 확인 하고 그렇다면 정수를 반환합니다 k-x mod k(즉, 백 바운스) x mod k.


이것은 아마도 맛의 문제 일 뿐이지 만 !바이트를 절약하지 않기 때문에 개인적으로 정의 하지 않는 것이 x#k|odd$x`div`k=k-x`mod`k|1<2=x`mod`k
Mark S.

1

PHP, 40 50 바이트

망할 달러. 가져 오기 오버 헤드가 너무 큽니다. :)

정수 버전 :

[,$x,$k]=$argv;$y=abs($x)%$k;echo$x/$k&1?$k-$y:$y;

또는

[,$x,$k]=$argv;echo[$y=abs($x)%$k,$k-$y][$x/$k&1];

float 버전, 56 바이트 :

교체 abs($x)%$k와 함께 fmod(abs($x),$k).


편집 : 부정에 대한 고정 결과 x


4
"멍청한 달러". 그래, 돈 냄새가 난다 ...
steenbergh

2
방법에 대해 €argv£argv? 그들은 잘 보일 것입니다 : x
Ismael Miguel

1

자바 스크립트 (ES6), 36 32 바이트

k=>f=x=>x<0?f(-x):x>k?k-f(k-x):x

도전 정신의 정신에서 와 에 x대해 재귀 적으로 튀어 오릅니다 .0k



0

C (gcc), 43 53 바이트

편집 : 부정적인 문제 수정

int f(int x,int y){return x/y%2?abs(y-x%y):abs(x%y);}

온라인으로 사용해보십시오!


2
이것은 (-13, 14) (13 대신 -13)에 대한 오답을 제공합니다. 모듈러스와 나머지 연산은 음수에서 다르게 동작합니다.
CAD97

0

R, 28 바이트

pryr::f(abs((x-k)%%(2*k)-k))

어떤 기능으로 평가 :

function (k, x) 
abs((x - k)%%(2 * k) - k)

대부분의 솔루션이 사용하는 방법으로 보입니다. 나는 이것을 만들기 전에 그들을 보지 않았다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.