모든 길이의 주기로 함수 찾기


11

함수가 가지고 있다고 길이의주기를 N 가 존재하는 경우 , X가 그 도메인되도록 F N (X) = (X)(F) m (X) ≠ X0 <m <N , 첨자 N 이고 N - f의 접힘 적용 . 길이 1 의주기 는 고정 점 f (x) = x 입니다.

당신의 작업은 구현하는 것입니다 전단 사 함수를 모든 긍정적 인 길이의 단 하나의주기를 가지고 자신의 정수에서, N을 . bijective 함수는 일대일 대응, 즉 모든 정수가 정확히 한 번 매핑됩니다. 길이가 정확히 하나의 사이클을 갖는 N 정확히 있다는 것을 의미 N 고유 번호 X 되는 F N (X) = XF m (x)가 X ≠0 <m <N을 .

다음은 그러한 함수가 x = 0 주위에 어떻게 보이는지에 대한 예입니다 .

x     ... -7 -6 -5 -4 -3 -2 -1  0  1  2  3  4  5  6  7 ...
f(x)  ...  2  4  6 -3 -1  1 -4  0 -2  5  7 -7 -6  3 -5 ...

이 발췌문에는 길이 1 ~ 5의 주기가 포함되어 있습니다 .

n   cycle
1    0
2   -2  1
3   -4 -3 -1
4   -5  6  3  7
5   -7  2  5 -6  4
...

위에서 저는 수학적인 의미에서만 "함수"를 사용하고 있습니다. 단일 부호있는 정수를 입력으로 사용하고 단일 부호있는 정수를 반환하는 한 선택한 언어로 함수 또는 전체 프로그램을 작성할 수 있습니다. 평소와 같이 STDIN, 명령 줄 인수, 함수 인수 등을 통해 입력을 받고 STDOUT, 함수 반환 값 또는 함수 (출력) 인수 등을 통해 출력 할 수 있습니다.

물론 많은 언어는 (임의의) 임의 정밀도 정수를 지원하지 않습니다. 적어도 [-127, 127] 범위를 포함 하고 언어의 정수 유형이 임의의 정수로 대체되면 임의의 정수 에 대해 작동하는 한, 구현이 언어의 기본 정수 유형의 범위에서만 작동하는 것이 좋습니다. 정밀 정수.

표준 규칙이 적용됩니다.


2
밀접하게 관련. 차이점은 사소한 것처럼 보이지만 이전 방식 중 어느 것도 큰 수정 없이는 작동하지 않는다는 것을 암시하며, 특히 그 도전에서 얻은 접근 방식을 전혀 적용 할 수 없다고 생각합니다.
마틴 엔더

"길이마다 정확히 하나의주기가있다", "길이가 많은주기가있다": 이것이 유일한 차이는 다른 것과 다른가?
Abr001am

@ Agawa001 또 다른 차이점은 다른 도전은 양의 정수에 대한 함수에 관한 것이고,이 도전은 모든 정수에 대한 함수를 요구한다는 것입니다.
마틴 엔더

1
사이클 정의에 n이 최소라는 것을 포함시켜야한다고 생각합니다. 그렇지 않으면 길이 2의 주기도 길이 4와 6의 주기로 계산됩니다.
xnor

@ xnor 으악, 좋은 지적.
마틴 엔더

답변:


2

Pyth, 27 18 바이트

_h?gQ0^2Q*.5@,Q-xh

설명 (Pyth Q가 입력 정수로 초기화 됨) :

_                       negative of (
                          (
  ?gQ0                      if Q >= 0:
      ^2Q                     2**Q
                            else:
         *.5                  half of
            @        Q          element Q (modulo list length) in
             ,                    the two element list [
              Q                     Q,
                 hQ                 ((Q plus 1)
                x  Q                 XOR Q)
               -    Q               minus Q
                                  ]
 h                        ) plus 1
                        )

이 사이클이

(−1)
(0, -2)
(1, -3, -4)
(2, -5, -7, -6)
(3, -9, -13, -11, -8)
(4,- 17, -25, -21, -15, -10)
(5, -33, -49, -41, -29, -19, -12)
(6, -65, -97, -81, -57, -37, -23, -14)
(7, -129, -193, -161, -113, -73, -45, -27, -16)
(8, -257, -385, -321, -225 , -145, -89, -53, -31, -18)
(9, -513, -769, -641, -449, -289, -177, -105, -61, -35, -20)

길이의주기 N이 주어진다

( n -2,
-2 ^ ( n -2) ⋅1-1,
−2 ^ ( n -3) ⋅3-1,
−2 ^ ( n −4) ⋅5-1,
…,
−2 ^ 2 ⋅ (2 · n − 7) − 1,
−2 ^ 1⋅ (2 · n − 5) − 1,
−2 ^ 0⋅ (2 · n − 3) − 1).

각 정수 k ≥ -1은 ( k + 2) 사이클 의 첫 번째 요소로 나타납니다 . 각각의 정수 k <-1에 대해, 일부 i , j ≥ 0에 대해 1- k = 2 ^ i ⋅ (2⋅ j + 1)을 고유하게 쓸 수 있습니다 . 다음 k는 제 (같이 나타날 J + 2) (th 요소의 + J + 2) -cycle.


5

MATL , 47 바이트

E|G0<-QXJ:tQ*2/0hStJ<f0))Q2MQ)&:J6M-)2/ttk>Eq*k

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

일반적인 설명

아래 기능 2는 @ Sp3000의 관련 문제에 대한 답변 에서 사용 된 것과 동일 합니다. 알려 주셔서 @ Agawa001에게 감사합니다.

이 기능은 세 가지 구성입니다.

  1. 전단 사 함수부터 Z 까지 (정수) N 합니다 (내츄럴).
  2. 원하는 특성 (각 길이의 한 사이클) 으로 N 에서 N 으로의 궤적 .
  3. 기능의 역수

함수 1과 3은 Z 보다 N 에서 원하는 동작을 달성하는 것이 더 쉽기 때문에 사용됩니다 .

기능 2는 다음과 같습니다. 상단 라인은 도메인이고 하단 라인은 코 도메인입니다. 쉼표는 명확성을 위해 사용됩니다.

1,  2  3,  4  5  6,  7  8  9  10  ...
1,  3  2,  6  4  5, 10  7  8   9  ...

첫 번째 블록 (위에서 1아래로 1)은 길이 1의주기입니다. 두 번째 (부터 2 33 2)는 길이 2의주기입니다. 각 블록에서 하부 (함수의 이미지)는 원형으로 시프트 된 상부입니다. 한 단계 오른쪽에.

기능 1은 다음과 같습니다.

 -5  -4  -3  -2  -1   0  +1  +2  +3  +4  ...
+10  +8  +6  +4  +2  +1  +3  +5  +7  +9  ...

기능 3은 두 줄이 바뀐 1과 같습니다.

의 이미지는 3입니다 -5. 먼저 함수 1 37의해 맵핑됩니다 . 그런 다음 기능 2 710의해 맵핑됩니다 . 그런 다음 10함수 3에 의해 -5에 매핑됩니다.

길이 1주기는입니다 0. 길이 -2주기는입니다 -1 1. 길이 3주기는 -3 2 -2등입니다.

코드 설명

기능 1과 3은 간단합니다.

기능 2는 해당 입력 블록의 하단 끝점을 찾아 작동합니다. 예를 9들어이 기능에 대한 입력이 발견되면 7위의 블록을 참조하십시오. 그런 다음 10예제에서 상단 끝점을 선택합니다 . MATL의 1 기반 모듈 식 인덱싱 덕분에 블록의 원형 이동이 가능합니다.

         % FUNCTION 1
         % Implicit input
E|       % Multiply by two. Absolute value
G0<      % 1 if input is negative, 0 otherwise
-        % Subtract
Q        % Add 1
XJ       % Copy to clipboard J. Used as input to the next function

         % FUNCTION 2
:        % Range [1 2 ... J], where J denotes the input to this function
tQ*      % Duplicate, increment by 1, multiply
2/       % Divide by 2
0hS      % Prepend a 0. This is needed in case J is 0
tJ<f     % Duplicate. Find indices that are less than the input J
0)       % Pick the last index.
)        % Apply as index to obtain input value that ends previous block
Q        % Add 1: start of current block
2M       % Push the two arguments to second-to-last function call
Q)       % Add 1 and use as index: end of current block
&:       % Inclusive binary range: generate input block 
J        % Push J (input to function 2)
6M-      % Subtract start of block
)        % Apply as index (1-based, modular). This realizes the shifting

         % FUNCTION 3
2/       % Divide by 2
ttk>     % Duplicate. 1 if decimal part is not 0; 0 otherwise
Eq       % Multiply by 2, add 1
*        % Multiply
k        % Round down
         % Implicit display

이것은 sp3000 기능의 비틀림입니다.
Abr001am

@ Agawa001 아 그래? 나는 다른 도전을 보지 못했습니다. 내가 보자
Luis Mendo

오. 확실합니다. 원래하지 않을 경우 적어도 내 추론, :-) 정확 관계를 설명하는 것이 그
루이스 Mendo

긴밀한 아이디어를 발산하기 위해 둘 이상의 마음이 어떻게 밀접하게 구성되어 있는지는 놀랍습니다.
Abr001am

4

파이썬 2, 55 바이트

g=lambda n,k=1:n/k and~g(~n+k*(n>0),k+1)+k*(n>0)or-~n%k

59 바이트 :

g=lambda n,k=1:n<0and~g(~n,2)or n/k and k+g(n-k,k+2)or-~n%k

사이클을 만듭니다

[0]
[-1, -2]
[1, 2, 3]
[-3, -4, -5, -6]
[4, 5, 6, 7, 8]
...

에서 수정 된 이전 문제에 대한 내 솔루션 에서 수정, SP3000의 건설 .

함수

g=lambda n,k=1:n/k and k+g(n-k,k+2)or-~n%k

음수가 아닌 홀수 크기의 사이클을 만듭니다.

[0]
[1, 2, 3]
[4, 5, 6, 7, 8]
...

올바른 사이클 크기를 찾으려면 결과가 간격이 될 때까지 k입력을 n아래로 이동하십시오 . 이 구간을 작업으로 순환 한 다음 입력에서 수행 된 모든 빼기를 취소합니다. 에 의해 재귀 적으로 구현됩니다 .k=1,3,5,7,...[0,k)n->(n+1)%kk+g(n-k,k+2)

이제 우리는 짝수 사이클을 만들기 위해 부정적인 것을 필요로합니다. in g로 시작하도록 수정 하면 균일 한 크기의 사이클이 생깁니다.k=2g

[0, 1]
[2, 3, 4, 5]
[6, 7, 8, 9, 10, 11]
...

이들은 비트-보완을 통해 네거티브로 향합니다 ~. 따라서 n음수이면 간단히로 평가 g(n)합니다 ~g(~n,2).


나는 그것이 도움이되지만 계산하는 또 다른 방법이 있는지 모르는 k것 같다 Math.floor(Math.sqrt(n))*2+1.
Neil

@Neil 나는 산술적으로 경계와 사이클 크기를 결정하고 심지어 전체 계산을 그런 식으로 수행하는 것을 조사했지만 이러한 표현식은 파이썬에서 길고 재귀가 더 짧다는 것을 알았습니다.
xnor

3

파이썬 3, 110 바이트

나는 아직도 거기에 람다를 얻는 방법을 알아 내지 못했습니다.

n이 삼각형 숫자 [1,3,6,10,15,21,28 등 ...]이면 f (n)은 목록의 순서에 음수를 곱한 것입니다. 숫자가 음수이면 1 + 다음으로 작은 삼각형 수를 지정하십시오. 그렇지 않으면 증분하십시오.

예 : 5는 삼각형 숫자가 아니므로 1을 더하십시오.

다음 반복에는 6이 있습니다. 6은 삼각형 숫자이고 목록에서 3 번째이므로 -3이됩니다.

프로그램은 이러한 목록을 제공합니다

길이 1 : [0]

길이 2 : [1, -1]

길이 3 : [2,3, -2]

길이 4 : [4,5,6, -3]

길이 5 : [7,8,9,10, -4]

x=int(input())
if x<0:print((x**2+x)/2+1)
else:
 a=((8*x+1)**.5-1)/2
 if a%1:print(x+1)
 else:print(-a)

편집 : 초과 문자를 제거해 주신 @TuukkaX에게 다시 감사드립니다.


1
당신은 변경 될 수 있습니다 0.5.5input('')input().
Yytsi

2

파이썬 3, 146 바이트

0보다 큰 모든 수에는 짝수 루프 (len 2,4,6,8 ...)가 있고 홀수 루프 (1,3,5,7)는 0보다 작습니다. 0은 0에 매핑됩니다.

(-3, -2, -1), (0), (1,2), (3,4,5,6)

에 매핑

(-2, -1, -3), (0), (2,1), (6,3,4,5)

f=lambda x:1+2*int(abs(x)**.5)if x<1 else 2*int(x**.5+.5)
x=int(input());n=f(x)
if x>0:b=n*(n-2)/4
else:b=-((n+1)/2)**2
print(b+1+(x-b-2)%n)

편집 : @TuukkaX는 이전 솔루션에서 8 바이트를 벗어났습니다. 그리고 또 다른 3.


1
내가 생각하는 첫 번째 줄에서 if 문 전에 공백을 제거 할 수 있습니다. 그리고 mi같은 작은 뭔가 변경 될 수 있습니다 b.
Yytsi

다음은 같은 프로그램으로 시작되었습니다.f=lambda x:1+2*int(abs(x)**0.5)if x<1 else 2*int(x**0.5+0.5) x=int(input()) n=f(x) if x>0:b=n*(n-2)/4 else:b=-((n+1)/2)**2 print(b+1+(x-b-2)%n)
Yytsi

1
감사합니다, @TuukkaX. 2 문자 변수 'mi'를 잊어 버렸습니다.
Magenta

1
또한로 변경 input('')되었습니다 input(). 따옴표는 입력을 얻으려고 할 때 콘솔에 아무것도 인쇄 할 필요가 없으므로 쓸모가 없습니다.
Yytsi

1
더 짧습니다. 점 앞에있는 0을 제거했습니다. f=lambda x:1+2*int(abs(x)**.5)if x<1 else 2*int(x**.5+.5) x=int(input());n=f(x) if x>0:b=n*(n-2)/4 else:b=-((n+1)/2)**2 print(b+1+(x-b-2)%n)
Yytsi

2

MATLAB (423)

function u=f(n),if(~n)u=n;else,x=abs(n);y=factor(x);for o=1:nnz(y),e=prod(nchoosek(y,o)',1);a=log(x)./log(e);b=find(a-fix(a)<exp(-9),1);if ~isempty(b),k=e(b);l=fix(a(b));break;end;end,if(abs(n)==1)k=2;l=0;end,if(k==2)l=l+1;x=x*2;end,e=dec2base(l,k)-48;o=xor(e,circshift(e,[0 1]));g=~o(end);if(~o|nnz(o==1)~=numel(e)-g),u=n*k;else,if((-1)^g==sign(n)),u=sign(n)*k^(base2dec([e(2:end-1) 1]+48,k)-(k==2));else,u=n*k;end,end,end
  • 비경쟁은 가능한 한 그것을 줄이기 위해 고군분투하는 동안 마지막 순위에 대한 좋은 조건을 깨기 때문에 경쟁이 아닙니다.

  • matlab의 정확도와 관련하여 일부 코드를 비싸게 만드는 것을 제외하고는 어떤 방법도 찾을 수 없었습니다. 다른 한편으로는 내가 선택한 매핑은 주요 facors 및 n-ary logarithm과 관련이 있습니다.

실행

 f(2)

 1

 f(1)

 2

 f(-2)

 -4

 f(-4)

 -8

 f(-8)

 -1

 f(0)

 0



 ----------------------------

설명

  • Knonwing은 먼저이 N=e1^x1*e2^x2...베이스에서 소수의 소수의 곱으로 쓸 수 있다는 C점을 알고 있습니다 .N은 완벽한 거듭 제곱이라는 가장 작은 요소 (소수는 아닙니다)의 가장 큰 지수에서 추출 된 사이클 이미지를 매핑하기로 결정했습니다. .

  • 간단히 말하면, N=P^xP가 가장 작은 완전 근인 곳을 봅시다 . x사이클에 대한 두 가지 필수 항을 정확하게 나타냅니다 x=Ʃ(r*P^i). 항 P은주기의 기초이자 기본 수 N의 완전한 근 k이며, 사이클의 정도입니다 C=p^k. i1과 K 사이의 변화는 coeffecient는 r모든 coeffecients이 R = 1로 설정 될 때까지, 우리는 그주기의 시작으로 이동하므로, 모든 다음의 사전 이미지 P-1으로 1 씩 증가와 묶여있다.

  • 사이클 사이의 충돌을 피하기 위해 두 사이클의 기본 사이클 32그 사이의 만남의 예가 될 수 있기 때문에 제품보다 소수의 지수 선택이 정확 3*2합니다. 기준점 및 기준점에 대한 기준 6과 차수 1 의 다른주기가 있습니다 .

  • 음수는 예외로, 음수는 홀수도, 나머지는도를 예약합니다. 어떻게 그렇게?

    사이클 내에 포함 된 임의의 수 N에 대해 P^k,로 표기되고 P^(a0*P^i0+a1*P^i1+...), (p = 2) 서열이 이진 염기에 있어야하는 경우이 점을 명확하게하기 위해 양은 (a0*P^i0+a1*P^i1+...)P-ary 염기에로 변환 a0,a1,....된다. 포지티브 / 네거티브 정도의 조건과 (+/- 1) 예외를 설정하지 않고 사전에 알려진 바와 같이 k, 시퀀스 A가 모든 염기 로 1111..{k+1}..10또는 111..{k}..1모든 염기에 대해 기록 된 경우에만 숫자 N은 정도의 사이클 가장자리에 있습니다. 회전이 필요하지 않으므로 k/k'둘 다 에 대해 각각의 홀수 / 짝수도에 대해 음수 / 양수 조건을 할당 하면 홀수 시퀀스가 ​​양식으로 작성되고 101..{k}..100짝수 시퀀스는 101..{k'}..10각각 음수 / 양수 사이클의 시작 가장자리 에 대해 양식으로 작성됩니다 .

    예:

    을 추진하고 N=2^10, x=10=2^1+2^3시퀀스 (A)는 기입 A=1010, 서열이 유형은 양수 사이클의 한정된 에지 symptomizes C=2^3다음 이미지가 가장자리 초의하므로, A=011이다 8, 그러나, 이 결과를 standarizing하여 (+ / -) 1 개의 예외 2^10/28/2과 이전 이미지를 회전해서는 안됩니다.

    을 추진하고 N=-3^9, x=9=3^2시퀀스 (A)는 기입 A=100순서의이 유형은 음수 사이클의 한정된 에지 symptomizes C=3^1다음 이미지가 가장자리 초의 그래서, A=013음극 / 양극이 결과를 적용하여, 그러나 조건이에 -3^9매핑됩니다 -3.

  • 커플의 경우 (-/+)1, 2순환 그룹 의 수 내에서 그것을 침범하려고 생각했습니다. 순환 그룹의 일반적인 순서가 {2,4}{8,16,32,64}..다른 형태로 구성되어 {1,2}{4,8,16,32}..이전 요소의 손실을 방지하고 완료된 작동은 팝으로 변경됩니다. 새로운 요소


결과 :

이 작은 코드 시트를 실행하여 첫 번째 합리적인 범위의 순환 숫자를 확인하십시오.

for (i=1:6) 
index=1;if(max(factor(i))>=5) index=0;end
for ind=0:index
j=f(((-1)^ind)*i); while(((-1)^ind)*i~=j)fprintf('%d ',j);j=f(j);end,fprintf('%d \n',(-1)^ind*i),pause,end,
end

이 결과로 이어집니다

 2 1 
 -2 -4 -8 -1 
 1 2 
 -4 -8 -1 -2 
 9 27 3 
 -9 -27 -81 -243 -729 -2187 -6561 -19683 -3 
 8 16 32 64 128 256 512 4 
 -8 -1 -2 -4 
 25 125 625 3125 5 
 36 216 1296 7776 46656 6 
 -36 -216 -1296 -7776 -46656 -279936 -1679616 -10077696 -60466176 -362797056 -2.176782e+009 -1.306069e+010 ??? Error using ==> factor at 27

마지막은 세그먼테이션 오류이지만 [-127,127] 표준 부호있는 정수 범위에 맞습니다.


나는이 기술을 오래 전에 내 오래된 C 프로그램에서 해시 함수를 정의하기 위해 사용했는데 깔끔하게 작동합니다!
Abr001am

0

자바 스크립트 (ES6), 73 바이트

f=(n,i=0,j=0,k=0,l=1,m=i<0?-i:~i)=>n-i?f(n,m,k++?j:i,k%=l,l+!k):++k-l?m:j

찾을 때까지 시퀀스 (0, -1, 1, -2, 2, -3, 3, ...)를 열거하여 작동합니다 n. i현재 항목을 포함합니다.j현재주기의 시작 k,주기 내의 색인 , 현재주기 l의 길이 및 m순서의 다음 항목을 포함합니다. 일단 우리가 발견 하면 우리는 사이클의 끝에 있는지 아닌지 n를 취 j합니다 m.

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