กำหนดฟังก์ชัน f เช่น f (f (n)) = -n สำหรับจำนวนเต็มทั้งหมดที่ไม่เป็นศูนย์ n


43

ความท้าทายนี้ได้รับแรงบันดาลใจจากบล็อกการเขียนโปรแกรมที่ฉันใช้บ่อย โปรดดูโพสต์ต้นฉบับที่นี่: ปริศนาการเขียนโปรแกรม


ท้าทาย

กำหนดฟังก์ชั่นf:Q->Qเช่นนั้นf(f(n)) = -nสำหรับจำนวนเต็มทั้งหมดที่ไม่เป็นศูนย์nและQเป็นชุดของจำนวนตรรกยะ

รายละเอียด

ในสิ่งที่ภาษาที่คุณต้องการกรุณากำหนดหนึ่งฟังก์ชั่นหรือโปรแกรมfที่ยอมรับเป็นพารามิเตอร์หนึ่งจำนวนnและผลตอบแทนหรือผลอย่างใดอย่างหนึ่งf(n)จำนวน

อาจมีการป้อนข้อมูลผ่านกลไกใดก็ตามที่เป็นธรรมชาติที่สุดสำหรับภาษาของคุณ: อาร์กิวเมนต์ฟังก์ชั่น, อ่านจาก STDIN, อาร์กิวเมนต์บรรทัดคำสั่ง, ตำแหน่งสแต็ค, อินพุตเสียง, สัญญาณแก๊งค์ ฯลฯ

เอาต์พุตควรเป็นค่าส่งคืนจากฟังก์ชัน / โปรแกรมหรือพิมพ์ไปยัง STDOUT

ผมอยากจะ จำกัด คำตอบให้กับฟังก์ชั่นที่ไม่ได้ใช้ประโยชน์ของรัฐโปรแกรมหรือหน่วยความจำระดับโลก / fข้อมูลที่สามารถมองเห็นจากด้านนอกของฟังก์ชั่น ตัวอย่างเช่นการรักษาตัวนับนอกfจำนวนสิ่งที่fถูกเรียกและเพียงแค่การปฏิเสธตามจำนวนนี้ไม่ได้ท้าทายหรือน่าสนใจสำหรับทุกคน การตัดสินใจfควรอาศัยข้อมูลในfขอบเขตของคำศัพท์เท่านั้น

อย่างไรก็ตามข้อ จำกัด นี้อาจไม่เหมาะสมสำหรับภาษาที่เน้นกองซ้อนหรือภาษาประเภทอื่นที่ไม่แยกความแตกต่างของข้อมูลหรือขอบเขตเหล่านี้ โปรดใช้วิจารณญาณที่ดีที่สุดของคุณเพื่อรักษาจิตวิญญาณของความท้าทายนี้


เกณฑ์การให้คะแนน

กฎกอล์ฟทั่วไปที่บังคับใช้ - คะแนนของคุณคือจำนวนไบต์ในซอร์สโค้ดของคุณ

คำตอบน้อยที่สุดต้องมีโดเมนและโคโดเมนของfที่จะเป็นส่วนหนึ่งของ Qrationals หากคุณ จำกัด โดเมนและโคโดเมนของคุณfเป็นจำนวนเต็มZคะแนนของคุณจะอยู่ที่ 90% ของจำนวนไบต์ในซอร์สโค้ดของคุณ

เบรค

ในกรณีที่เสมอการต่อไปนี้จะถูกใช้ตามลำดับ:

  1. จำนวนสัญลักษณ์ที่ไม่ใช่ช่องว่างที่พิมพ์ได้น้อยที่สุดในซอร์สโค้ดของคุณ
  2. วันที่และเวลาที่ส่งคำตอบเร็วที่สุด

แก้ไข

คุณไม่จำเป็นต้องให้การสนับสนุนหมายเลขที่มีขนาดตามอำเภอใจ โปรดตีความชุดZและQเป็นประเภทข้อมูลในภาษาที่คุณเลือก (โดยทั่วไปจะเป็นจำนวนเต็มและจุดลอยตัวตามลำดับ)

หากโซลูชันของคุณขึ้นอยู่กับโครงสร้างพื้นฐานหรือรูปแบบบิตของชนิดข้อมูลทั้งหมดโปรดอธิบายข้อ จำกัด และวิธีการใช้งาน


20
f (n) = i * n - คณิตศาสตร์บริสุทธิ์: P
Johannes Kuhn

8
@JohannesKuhn นี่เป็นเหตุผลว่าทำไมโดเมนและ codomain ถูก จำกัด ตามเหตุผล
ardnew

คุณช่วยอธิบายความf:Q->Qหมายได้อย่างไร
beary605

@ beary605 มันหมายถึงการfเป็นสมาชิกในการทำแผนที่การทำงานของQ(สรุปตัวเลข) เพื่อสมาชิกคนอื่น ๆ (อาจจะเหมือนกัน) Qของ ดูen.wikipedia.org/wiki/Function_(mathematics)#Notation
ardnew

7
ฉันรู้ว่าฉันเพิ่งเห็นสิ่งนี้เมื่อไม่นานมานี้ รุ่นน้อยกว่าที่ระบุไว้แน่นใน StackOverflowถูกปิดเมื่อเร็ว ๆ นี้ กว่า 100 คำตอบ
Peter Taylor

คำตอบ:


12

J, 9 คะแนน (10 ตัวอักษร)

ตามคำตอบของ stackoverflow :

   (*-[*_1&^)

ความคิดแรก (13 ตัวอักษร):

   ((-*)-2&|*+:)

   ((-*)-2&|*+:) _10 _9 _8 _7 _6 _5 _4 _3 _2 _1 0 1 2 3 4 5 6 7 8 9 10
_9 10 _7 8 _5 6 _3 4 _1 2 0 _2 1 _4 3 _6 5 _8 7 _10 9

   ((-*)-2&|*+:) _9 10 _7 8 _5 6 _3 4 _1 2 0 _2 1 _4 3 _6 5 _8 7 _10 9
10 9 8 7 6 5 4 3 2 1 0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _10

สิ่งนี้ใช้งานได้กับอินพุตจำนวนเต็ม แต่สิ่งนี้จะสร้างเอาท์พุทจินตภาพสำหรับค่าจุดลอยตัว (ฟังก์ชั่นจะต้องผลิตเอาต์พุตที่มีเหตุผลสำหรับอินพุตที่มีเหตุผลตามข้อกำหนด)
ความผันผวน

5
@ ความผันผวนของสเป็คทำให้เกิดความสับสน แต่เมื่อฉันอ่านมันจะอนุญาตให้ จำกัด โดเมนและโคโดเมนเป็นจำนวนเต็ม
Peter Taylor

คุณต้องการวงเล็บหรือไม่
Cyoce

14

Python: 61 34 30 29 27 คะแนน

f: Q -> Q

ในคณิตศาสตร์:

       | 0.5-x   if x is in Q \ Z
f(x) = |
       | x+0.5   if x is in Z

ใน Python:

f=lambda x:.5+[x,-x][x%1>0]

ทดสอบกับ

filter(lambda n: n[0] != -n[1], map(lambda n:(n,f(f(n))),range(0,50)))

ตรรกะที่อยู่เบื้องหลังสิ่งนี้:

เมื่อคุณใช้เวลาเป็นจำนวนเต็มnและใส่ลงในคุณจะได้รับf x+0.5นี่ไม่ใช่จำนวนเต็มดังนั้นแอปพลิเคชันถัดไปจะ0.5-(x+0.5)เป็นอัน-xใด

เครดิต

ขอบคุณ

  • Bakuriuสำหรับการสตริปมันลงมาจาก 61 ตัวอักษรถึง 34 ตัว
  • ความผันผวนสำหรับการลดขนาดรหัสอีก 30 ตัวอักษร
  • คัดลอกเพื่อลดขนาดรหัสเป็น 29 ตัวอักษร (และแก้ไขปัญหาจุดลอยตัวที่อาจเกิดขึ้น)
  • aditsu ที่กล่าวถึงความไม่สอดคล้องที่มาพร้อมกับการเปลี่ยนแปลงข้างต้น

หมายเหตุ

ตอนแรกฉันคิดว่ามันคงโอเค

f = lambda n: 1j*n

แต่มัน f: N-> C และที่ไม่ได้รับอนุญาต: - /


1
สามารถถอดออกได้เป็น: f=lambda x:x%1>0and(-x+x%1)or x+.1ซึ่งมีความยาวเพียง 34 ตัวอักษร
Bakuriu

f=lambda x:[x+.1,x%1-x](x%1>0)เพียง 30
ความผันผวน

1
ถ่านสั้นหนึ่งตัว: f=lambda x:[x+.5,.5-x][x%1>0]. หมายเหตุการใช้. 5 แทน. 1 เพื่อแก้ไขปัญหาความแม่นยำ
คัดลอก

1
@AJMansfield 1.48 ไม่ใช่จำนวนเต็ม
Martin Thoma

1
ไม่นั่นไม่ได้หมายความว่าอย่างนั้น ถ้าเขาพูดถึงเขาควรจะเขียนว่า "จำนวนตรรกยะทุกตัว" f:Q->Qไม่ได้หมายความว่า f แม็พจำนวนตรรกยะกับจำนวนตรรกยะ คำจำกัดความของ f คืออะไร
Martin Thoma

11

C, 41 คะแนน (41 หรือ 45 ตัวอักษร)

ทำงานได้ทั้ง 32- บิตและ 64- บิต

f : Z -> Z(ยกเว้นINT_MAX):

f(n){return (abs(n)%2*2-1)*n+n?(-n<n)*2-1:0;}

หากเราไม่จำเป็นต้องรวม0เราสามารถกำจัดตัวอักษรบางตัวออก (41 ตัวอักษร):

f : Z -> Z(ยกเว้น0& INT_MAX):

f(n){return (abs(n)%2*2-1)*n+(-n<n)*2-1;}

ฟังก์ชันนี้ทำงานโดยการหารจำนวนเต็มทั้งหมดเป็น 4 กลุ่มตามเครื่องหมายและพาริตี้

ดังนั้นเราจึงมีชุดค่าผสม 4 แบบ:

+ even, + odd, - even, - odd

เนื่องจากเราจำเป็นต้องเปลี่ยนสัญลักษณ์ของตัวเลข แต่ไม่ใช่ความเท่าเทียมกันหลังจากผ่านไปสองครั้งเราจึงได้ลำดับที่แตกต่างกันสองแบบ:

  + even -> - odd -> - even -> + odd -\
^-------------------------------------/

  + even -> + odd -> - even -> - odd -\
^-------------------------------------/

ในตัวอย่างนี้ฉันได้เลือกอันแรก

ก่อนอื่นเราต้องแมปจำนวนเต็มบวกทั้งหมดกับจำนวนเต็มลบคี่ เราทำสิ่งนี้โดยเปลี่ยนเครื่องหมายและเพิ่มจำนวน (คุณสามารถเลือกที่จะลดจำนวนแทน):

f1(n) = -n + 1

จากนั้นเราต้องแมปจำนวนเต็มลบทั้งหมดที่เป็นเลขคี่ เราต้องแน่ใจว่าf2(f1(n)) = -n:

f2(f1(n)) = -n
f2(-n + 1) = -n
f2(-n) = -n - 1
f2(n) = n - 1

ใช้วิธีการเดียวกันกับที่เราค้นหาf3และf4:

f3(n) = -n - 1
f4(n) =  n + 1

ในการรวมฟังก์ชั่นเหล่านี้ไว้ในฟังก์ชั่นเดียวเราสังเกตว่าทุกครั้งที่nมีการเปลี่ยนสัญลักษณ์nและทุกครั้งที่nบวกเราจะเพิ่มขึ้นทีละหนึ่งและมิฉะนั้นเราจะลดลงหนึ่ง:

f1(n) = -n + 1 (+ even)
f2(n) =  n - 1 (- odd)
f2(n) = -n - 1 (- even)
f4(n) =  n + 1 (+ odd)

ซึ่งสามารถเขียนใหม่เป็น:

f(n) = odd(n) * n + sign(n)

ที่odd(n)ส่งกลับ1สำหรับเลขคี่และ-1สำหรับเลขคู่

มี 4 โซลูชั่นทั้งหมด:

f(n) = odd(n) * n + sign(n)  (edge cases: f(f(0))  -> -2, f(f(INT_MAX))   -> -8)
f(n) = even(n) * n - sign(n) (edge cases: f(f(0))  -> -2, f(f(INT_MIN+1)) -> -6)
f(n) = odd(n) * n - sign(n)  (edge cases: f(f(1))  -> -3, f(f(INT_MIN))   -> -5)
f(n) = even(n) * n + sign(n) (edge cases: f(f(-1)) -> -1, f(f(INT_MIN))   -> -5)

INT_MINอาจได้รับการพิจารณาเป็นกรณีขอบทั้ง 4 ฟังก์ชั่นเป็น=>-INT_MIN == INT_MINf(f(INT_MIN)) = INT_MIN


นี่เป็นสิ่งเดียวกับ GolfScript ของฉัน (ยกเว้นอธิบายได้ดีกว่า) ใช้งานได้กับ 0 หรือไม่
Ben Reich

@BenReich ตามที่ระบุไว้ในคำตอบมันไม่ทำงาน0และ 3 หมายเลขอื่น ๆ
Tyilo

1
@Tylio ฉันเห็นตอนนี้ มีเหตุผล. ดูเหมือนว่าคุณควรรับZโบนัสหากคุณครอบคลุม 0 อย่างน้อย
Ben Reich

@BenReich ลบโบนัสจนกว่าฉันจะได้รับการแก้ไข
Tyilo

9

นี่ฉันไปที่มัน

long f(int i){return i;}
int f(long i){return -i;}

ตัวอย่างสด :

int main()
{
  for(int i=-10; i<10; i=i+3)
    std::cout << f(f(i)) << "\n";
}

ชนิดอินพุต cn ได้รับการออกแบบตามความต้องการของคุณโดยพลการ รุ่นนี้ใช้ได้กับตัวอักษรจำนวนเต็มที่มีขนาดเล็กกว่า 2 ^ 32-1


2
ปัญหาดังกล่าวไม่ได้f:Q->Q f:Z->Z
AJMansfield

@JMansfield ส่วนการให้คะแนนของสเป็คนั้นหมายถึงการให้คะแนนโบนัสสำหรับฟังก์ชั่นที่กำหนดf:Z->Zขออภัยในถ้อยคำที่สับสน
ardnew

6
ปัญหาที่เกิดขึ้นกับคำตอบนี้ดูเหมือนว่าจะกำหนดฟังก์ชั่นแยกกันสองฟังก์ชั่นในขณะที่ข้อมูลจำเพาะต้องการให้คุณกำหนดเพียงหนึ่ง แต่ฉันไม่ได้ตั้งใจที่จะเริ่มการอภิปรายความหมายมันยังคงเป็นวิธีการแก้ปัญหาที่รอบคอบมาก
ardnew

@ มาใหม่โอ้ใช่แล้ว ฉันถูกชี้ไปที่การคัดค้านที่ถูกต้องนี้เพียงไม่กี่วินาทีก่อนที่จะแบ่งปันกับ Lounge <C ++> ในการแชทดังนั้น ฉันสงสัยว่าคอมไพเลอร์ทำสิ่งนี้อย่างไร (ถ้ามันไม่ได้อยู่ในสายเรียกเข้า) แต่แอสเซมบลีของฉันแย่มาก
rubenvb

1
ฉันคิดว่าคุณสามารถลบช่องว่างในreturn -i
Cyoce

6

JavaScript, 18

f=n=>n%1?.5-n:n+.5

ใช้สัญลักษณ์ลูกศรไขมันใหม่ (Firefox 22)

รุ่นอื่น ๆ (18):

f=n=>n%1?-.5/n:.5/n

รุ่นก่อนหน้า (20):

f=n=>n-~~n?.5-n:n+.5

ตัวอย่าง:

> [-3,-2,-1,1,2,3].map(f).map(f)
[3, 2, 1, -1, -2, -3]

10
ดูเหมือนว่า JavaScript กำลังพัฒนาเป็น CoffeeScript
Peter Taylor

4

Mathematica 18

f=#+1/2-4#(#-⌊#⌋)&

นี่⌊...⌋คือฟังก์ชั่นพื้น มันใช้ตัวเลขที่มีเหตุผลเท่านั้น (ไม่ใช่รายการ, จำนวนเชิงซ้อน, ฯลฯ )

f[10]
f[f[10]]

21/2

-10

f[-5]
f[f[-5]]

-9/2

5


3

ภาษาแอสเซมบลี x86 (FASM) อาร์กิวเมนต์และผลลัพธ์อยู่ใน eax register

มันทำงานได้อย่างถูกต้องสำหรับ -2 ^ 30 <N <+ 2 ^ 30-1

รหัสสั่งการ 16 ไบต์

        use32

f_n:
        lea     edx, [2*eax]
        xor     edx, eax
        btc     eax, 30
        shl     edx, 1
        jnc     .end
        neg     eax
.end:
        retn

วางตัวเลขของคุณ; 2E30 จะเป็น 2 * 10 ^ 30 ไม่ใช่ 2 ^ 30 อย่างที่ฉันคิดว่าคุณต้องการ
Nick T

@NickT ความผิดพลาดของฉัน แก้ไขแล้ว.
johnfound

ฉันค่อนข้างมั่นใจว่าคุณควรนับจำนวนไบต์ในซอร์สโค้ด
nyuszika7h

3

Lisp ทั่วไป: 35 ไบต์

(defun f(x)(/(if(> 1 x)-1/2 1/2)x))

แบบแผน (และแร็กเก็ต): 36 ไบต์

(define(f x)(/(if(> 1 x)-1/2 1/2)x))

ไม่พอใจกับความคิดเห็นและคำอธิบาย:

(define (f x)
  (/             ;; divide
     (if (> 1 x) ;; if x is below 1 
         -1/2    ;; then -1/2 (the fraction)
         1/2)    ;; else 1/2 (the fraction)
      x))        ;; gets divided with x

ตัวเลขใด ๆxในจะกลายเป็นเศษซึ่งเป็นจำนวนที่แน่นอนจริงในทั้งสองภาษา[1,->]if1/2

ส่วนการหารจะกลายเป็น(/ 1/2 x)ดังนั้นเศษส่วนจะกลายเป็น1/(x*2)ซึ่งอยู่ด้านล่าง1เสมอ สำหรับ1มันจะเป็น1/2สำหรับ2มัน1/4ฯลฯ

สำหรับตัวเลขใด ๆ ที่ต่ำกว่า 1 ifจะเปลี่ยนเป็นเศษส่วน-1/2ซึ่งทำให้ฟังก์ชันทำเช่น(/ -1/2 x)นั้น-1/(2*x)แต่เนื่องจากเราสามารถคาดหวังว่าค่าจะเป็นผลมาจากการวิ่งครั้งก่อนเราจึงสามารถแทนที่ x สำหรับ 1 / (x * 2) ได้-1/((1/(x*2))*2) = -x

เช่นตั้งแต่1เปลี่ยนเป็น1/2แอปพลิเคชั่นที่สองคือ(/ -1/2 1/2) ==> -1


มันทำงานอย่างไร
AJMansfield

@AJMansfield เพิ่มข้อมูลบางส่วน เพียงแค่ถามว่ามีอะไรที่ไม่ชัดเจน การอ่านไวยากรณ์ LISP เหมือนกรีกถ้าคุณยังไม่ได้เรียนรู้และใช้เวลาหลายสัปดาห์กว่าจะคุ้นเคย
Sylwester

3

C, 60 (⌈66 * .9⌉)

int f(int x){if(!x&1||!~x)return ~x;if(x<0)return x-1;return x+1;}

นี่คือรุ่นที่ไม่มีเงื่อนไข:

int f(int x){
    if(!x&1 || !~x) return ~x;
    if(x<0) return x-1;
    return x+1;
}

วิธีนี้ใช้ได้กับจำนวนเต็มเท่านั้นจึงได้รับคะแนนโบนัส 90% ตอนแรกฉันเขียนด้วยภาษาจาวา แต่รู้ว่าโปรแกรมนี้โดยเฉพาะจะได้ประโยชน์จากตัวดำเนินการเชิงตรรกะแบบ C

ในฐานะที่มีจำนวนเต็มสอดคล้องกับไม่มี-INT_MIN, f(f(INT_MIN))ผลตอบแทนINT_MINแทน

การทำแผนที่พื้นฐานนั้นค่อนข้างง่ายเกี่ยวกับพีชคณิต การดำเนินการคำสั่งx=f(x)แทนที่ x ด้วย:

  • x+1ถ้าxเป็นบวกและคี่
  • -x+1ถ้าxเป็นบวกและสม่ำเสมอ
  • x-1ถ้าxเป็นค่าลบและคี่
  • -x-1ถ้าxเป็นลบและเท่ากัน

ผลลัพธ์ของแต่ละเคสจะอยู่ภายใต้เคสถัดไปในครั้งถัดไปที่ใช้ฟังก์ชันกับ x

-xในขณะที่คุณสามารถดูการเขียนกรณีกับกรณีต่อไปนี้มันถัวเฉลี่ย

รหัสนี้เป็นผลมาจากการทำให้ฟังก์ชั่นบางอย่างของฉลาดขึ้นสามารถใช้ประโยชน์จากโครงสร้างบิตของจำนวนเต็มบวกสองของ


3

> <> , 21 + 3 = 24 ไบต์, 22 คะแนน

:0)$:0($:1$2%2*-*+-n;

ใช้ตัวแปล Python อย่างเป็นทางการและใช้-vตัวเลือกบรรทัดคำสั่งเพื่อป้อนข้อมูลด้วยค่าใช้จ่าย 3 ไบต์

ฉันมีความรู้สึกว่านี่น่าจะดีกว่า - ฉันจะคอยดูและพยายามตีมัน

รับอินพุตnโปรแกรมเอาต์พุต

(n>0) - ((n<0) + n * (1 - 2*(n%2)))

ที่ไหน(n>0)และ(n<0)เป็นบูลีน นี่เทียบเท่ากับคำตอบ Python ของ Gelatin

(n>0) - (n<0) - n * (-1)**n

แต่><>ไม่ได้มีการสร้างขึ้นในผู้ประกอบการยกกำลังเพื่อให้เราใช้ในสถานที่ของ(1 - 2*(n%2))(-1)**n

สิ่งต่อไปนี้เป็นทฤษฎีทางคณิตศาสตร์ - อ่านว่า (และถ้ามี) คุณสนใจ:

ในฟังก์ชั่นใด ๆf: Z -> Zที่f(f(n)) = -nทุกคนnเข้าZมาเราจะเห็นได้ทันทีว่าf(f(f(f(n)))) = nหรือในคำอื่น ๆf^4คือฟังก์ชันตัวตน โดยเฉพาะอย่างยิ่งเป็นตัวผกผันและฟังก์ชันผกผันของมันคือf f^3ดังนั้นจึงfเป็นการเปลี่ยนแปลงของZและตั้งแต่f^4 = Idมันตามที่ทุกวงโคจร (หรือรอบ) ของfมีขนาดอย่างใดอย่างหนึ่ง1, หรือ24

f(0) = 0ถัดไปเราจะเห็นว่า พิสูจน์: f(0) = f(-0) = f(f(f(0))) = -f(0)ดังนั้นf(0) = 0ตามที่ต้องการ ตรงกันข้ามสมมติว่าxอยู่ในวงจรของความยาว1หรือเพื่อ2 f(f(x)) = xถ้า-x = xอย่างx = 0นั้น

จึงfถูกสร้างขึ้นทั้งหมด 4 รอบยกเว้นจุดคงที่ (1 รอบ) 0ที่

นอกจากนี้ทุก 4 รอบจะต้องมีรูปแบบ(x, y, -x, -y)และโดยการหมุนรอบ ๆ เราอาจคิดว่าxและyเป็นทั้งบวก ตรงกันข้ามทุกผลิตภัณฑ์ดังกล่าวในระยะเวลา 4 fรอบแบ่งจำนวนเต็มภัณฑ์กำหนดทางเลือกของ

ดังนั้นตัวเลือกแต่ละตัวจะfสอดคล้องกับกราฟกำกับที่มีจุดยอดเป็นจำนวนเต็มบวกอย่างเช่นว่าจุดยอดทุกจุดจะเกิดขึ้นกับลูกศรหนึ่งลูกทั้งตรงเข้าหรือออก 1แม่นยำมากขึ้นในรูปแบบของกราฟไม่มีทิศทางพื้นฐานทุกจุดสุดยอดมีปริญญาว่า (แต่ละ 4 รอบ(x y -x -y)ด้วยxและyบวกสอดคล้องกับลูกศรx --> y)

ฟังก์ชั่นในคำตอบนี้ (และอีกหลายคำตอบอื่น ๆ ที่นี่) สอดคล้องกับกราฟที่1 --> 2, และโดยทั่วไป3 --> 42k-1 --> 2k

กราฟดังกล่าวอยู่ใน bijection กับลำดับอนันต์ของคู่อันดับ(a_n, p_n)ที่แต่ละa_nเป็นจำนวนเต็มบวกและแต่ละคนp_nเป็นอย่างใดอย่างหนึ่ง0หรือ1: กำหนดลำดับ(a_1, p_1), (a_2, p_2), (a_3, p_3), ...เราคู่แรก1ด้วย1 + a_1และจากนั้นเรารูปแบบทั้งที่ลูกศร1 --> 1 + a_1หรือลูกศร1 + a_1 --> 1ขึ้นอยู่กับว่าp_1เป็นหรือ0 1โดยพื้นฐานแล้วลูกศรเป็นทั้ง<เครื่องหมายหรือสัญญาณขึ้นอยู่กับความเท่าเทียมกันของ>p_1

ต่อไปจะจำนวนเต็มบวกที่เล็กที่สุด unpaired kและนับขึ้นจากkตรงa_2ขั้นตอนการกระโดดข้ามหมายเลขใด ๆ ที่อยู่คู่กับสิ่งที่มีอยู่แล้ว จับคู่kกับผลลัพธ์และตั้งค่าทิศทางของลูกศรขึ้นอยู่กับp_2ข้างบน จากนั้นทำซ้ำกับ(a_3, p_3)ฯลฯ

ลูกศรแต่ละอันจะถูกกำหนดด้วยวิธีนี้ในที่สุดดังนั้นกระบวนการจึงถูกกำหนดไว้อย่างดี ฟังก์ชั่นในคำตอบตรงนี้เพื่อลำดับ(1,0), (1,0), (1,0), ...เนื่องจากในขั้นตอนnจำนวนเต็ม unpaired ที่เล็กที่สุดเป็น2n-1และไม่มีจำนวนเต็มขนาดใหญ่กว่า2n-1ได้รับการจับคู่กับอะไรเราจึงได้รับ2n-1 --> 2nสำหรับแต่ละn(ลูกศรจะเน้นวิธีนี้เพราะแต่ละp_nเท่ากับ0)

ความสำคัญเชิงซ้อนของเซตนี้คือ(N*2)^N = N^Nซึ่งตามวรรคสุดท้ายของคำตอบนี้เท่ากับ2^Nความสำคัญเชิงตัวเลขของจำนวนจริง


ตัวเลือกบรรทัดคำสั่งมักจะเป็นไบต์แต่ละตัว
แมว

@cat ดูส่วน "การเรียกใช้แบบพิเศษ" ที่โพสต์เมตานี้
mathmandan

2

หากต้องการแก้ไขคำตอบ J ก่อนหน้า (ฉันไม่มีชื่อเสียงเพียงพอที่จะแสดงความคิดเห็นกับต้นฉบับ):

(*+[*1-~2*2|])

มันแค่แทนที่_1&^ด้วย1-~2*2|]ซึ่งให้สัญญาณตรงข้าม ดังนั้นฉันจึงเปลี่ยน-เป็น+(ซึ่งมีความสำคัญกับอินพุต1และ_1) เท่านั้น

นี่คือการทดสอบ:

   (*+[*1-~2*2|])6 3 _9 _8 1r2 _4.6 0 1 _1
7 _2 8 _9 1 7.28 0 2 _2
   (*+[*1-~2*2|])7 _2 8 _9 1 7.28 0 2 _2
_6 _3 9 8 0 _10.3568 0 _1 1

   NB. f^:2 = f@:f
   (*+[*1-~2*2|])^:(2)6 3 _9 _8 1r2 _4.6 0 1 _1
_6 _3 9 8 2 _5.0832 0 _1 1

อย่างที่คุณเห็นโดเมนและช่วงนั้นเป็นของจำนวนจริงทั้งหมด แต่ใช้ได้กับจำนวนเต็มเท่านั้น (รวมถึง 0)

คำอธิบาย:

(   *     + [ *  1-~    2*     2|]    )
 signum n + n * pred (twice (n mod 2))

2

GolfScript ceiling(26*.9)=24

Golfscript จัดการเฉพาะจำนวนเต็มดังนั้นใช้Zโบนัสรวม 24 คะแนน:

.{..0>2*(\)2%!2*(@*+}{ }if

กรณีพิเศษ 0 บัญชีสำหรับ 8 ตัวอักษร ไม่สนใจ 0 เราสามารถมีคำตอบ 17 คะแนน:

..0>2*(\)2%!2*(@*+

รหัสนี้ทำดังต่อไปนี้กับจำนวนเต็มxด้านบนของสแต็ก:

  • ถ้าxเป็น 0 ให้ปล่อย0กองไว้และไม่ใช้กฎอีก
  • หากxเป็นเช่นxนั้น
  • หากเป็นบวกเพิ่มx1
  • ถ้าเป็นลบลบx1

สิ่งนี้มีเหตุผลเชื่อมโยงชุดตัวเลข 4 ตัวในรอบที่ซึ่งfองค์ประกอบการสำรวจของรอบและมุมตรงข้ามของรอบเป็นเชิงลบของกันและกัน ทุกจำนวนเต็มเป็นส่วนหนึ่งของวัฏจักรดังกล่าว 1 ยกเว้น 0 ซึ่งเป็นกรณีพิเศษ ตัวอย่างเช่นสำหรับ{-8, -7, 7, 8}:

  • 7 f -> 8
  • 8 f -> -7
  • -7 f -> -8
  • -8 f -> 7

กรณีทดสอบที่เกี่ยวข้องเท่านั้นที่ฉันคิดได้ว่าเป็นเลขคี่เชิงลบ, ลบแม้แต่, คี่บวก, บวกแม้0, และจากนั้นฉันก็โยนเข้า-1และ1เนื่องจากความใกล้ชิดของพวกเขา0อาจทำให้เกิดปัญหา:

[-10 -5 -1 0 1 5 10]
{.{..0>2*(\)2%!2*(@*+}{ }if}:f;
{f f}%
-> [10,5,1,0,-1,-5,-10]

ฉันแน่ใจว่า GolfScript จริงสามารถปรับปรุงได้บ้าง ไม่รู้สึกว่าควรใช้ตัวอักษรถึง 26 ตัว! ชอบที่จะได้ยินคำแนะนำบางอย่าง


2

Java เพื่อความสนุก

นี่คือการใช้งานที่ทำ bijection จริงระหว่างℤถึงℤ²ซึ่งเป็นฟังก์ชั่นคี่ในเวลาเดียวกัน (g (-x) == -g (x)) มันจะถือว่าองค์ประกอบℤ²ที่สอดคล้องกันเป็นจำนวนเชิงซ้อนและคูณด้วย "i" จากนั้นแปลงกลับเป็นℤ

f (x) = g⁻¹ (ig (x))
f (f (x)) = g⁻¹ (-g (x)) = - x

ฟังก์ชั่นทำงานใน O (1)

public class Ffn {
    public static int f(int n) {
        if (n == 0) {
            return 0;
        }
        // adjust sign
        int s = n > 0 ? 1 : -1;
        int m = n * s;
        // calculate square "radius"
        int r = (int) (Math.sqrt(2 * m - 1) + 1) / 2;
        int q = r * 2;
        // starting point
        int x = r, y = r;
        int k = q * (r - 1) + 1;

        if (m - k < q) {
            // go left
            x -= m - k;
        }
        else {
            // go left
            x -= q;
            // go down
            y -= m - k - q;
        }

        // multiply by i
        int x2 = -y * s, y2 = x * s;
        // adjust sign
        s = y2 < x2 || y2 == x2 && x2 < 0 ? -1 : 1;
        x2 *= s;
        y2 *= s;

        if (y2 == r) {
            // go left
            k += r - x2;
        }
        else {
            // go left and down
            k += q + r - y2;
        }
        return k * s;
    }

    public static void main(final String... args) {
        for (int i = 0; i < 1000000; ++i) {
            if (f(f(i)) != -i || f(f(-i)) != i) {
                System.out.println(i);
            }
        }
    }
}

ปล. สวัสดีปีใหม่!


ฉันเชื่อว่าช่องว่างไม่จำเป็น
pppery

2

Python 3 - 38

คล้ายกับคำตอบของ @ moose แต่, f(n) == n. ใช้งานได้กับค่าจำนวนเต็มทั้งหมด

f=lambda x:x*(isinstance(x,int)*2.0-1)

2

Perl, 33 (ไม่ใช่ช่องว่าง)

sub f{($=)=@_;$=-$_[0]?-$=:"$=.1"}

แก้ไข:

  • $=.".1"สั้นลงไป"$=.1"(ขอบคุณ ardnew)

คณิตศาสตร์:

คณิตศาสตร์

Ungolfed:

# script.pl
sub f {
  ($=) = @_;   # short for $= = int($_[0]); 
               # "int" is implicit in assignments to $=;
               # ($=) can be prepended by "local" to get
               # the function free of side effects.

  $= - $_[0] ? # short for $= != $_[0], check if input is integer
    -$=        # input is not an integer  
  : $= . ".1"  # input is integer
}  

# Testing
chomp;
$_ = sprintf "f(f($_)) = f(%s) = %s\n", f($_), f(f($_));

ตัวอย่าง:

perl -p script.pl
7
f(f(7)) = f(7.1) = -7
2
f(f(2)) = f(2.1) = -2
0
f(f(0)) = f(0.1) = 0
-1
f(f(-1)) = f(-1.1) = 1
-10
f(f(-10)) = f(-10.1) = 10
-1.23
f(f(-1.23)) = f(1) = 1.1
3.4
f(f(3.4)) = f(-3) = -3.1
1.0
f(f(1.0)) = f(1.1) = -1

โซลูชันที่มีประสิทธิภาพ - กรณีทดสอบจุดลอยตัวที่คุณสาธิตไม่จำเป็นต่อข้อกำหนด (ควรให้คะแนนโบนัสสำหรับสิ่งนั้น!) นี่คืออัลกอริทึมเดียวกันของคุณโดยมีการสะสางบางอย่างเข้ามาที่ 22 ตัวอักษร:sub f{yzxzzc?-$_:x.$_}
ardnew

1
@ardnew: ขอบคุณ แต่ฉันไม่เห็นด้วยว่าโซลูชันของคุณใช้อัลกอริทึมเดียวกัน อัลกอริทึมsub f{yzxzzc?-$_:x.$_}จะไม่ได้$_รัฐอิสระจะใช้รัฐผ่านตัวแปร ด้วยเหตุนี้fจึงไม่มีฟังก์ชั่นอีกต่อไป (ในแง่คณิตศาสตร์) เนื่องจากค่าที่ต่างกันเป็นไปได้สำหรับค่าอินพุตเดียวกันขึ้นอยู่กับสถานะ (สภาพอากาศ$_มีxหรือไม่) อัลกอริทึมของฉันไม่ได้ใช้สถานะข้อมูลถูกเข้ารหัสในค่าผลลัพธ์ .1จำนวนเต็มจะถูกแปลงเป็นตัวเลขจริงโดยการเพิ่ม และจำนวนจริงจะถูกแปลงกลับเป็นจำนวนเต็มโดยมีการสลับเครื่องหมาย
Heiko Oberdiek

interesting- ไม่มีข้อมูลที่รัฐจะใช้ในการดำเนินงานของคุณเพราะของที่ได้รับมอบหมายครั้งแรกและไม่ได้เพราะคุณสมบัติพิเศษบางอย่างของ$=?
ardnew

ฉันไม่ได้ตระหนักถึงฉันก็ล้มเหลวความต้องการของตัวเอง (ที่fกำหนดไว้Q->Q) กับตัวxละครตัวนั้น นอกจากนี้ยัง$=.".1"สามารถย่อให้สั้น"$=.1"
ardnew

@ardnew: คุณสมบัติพิเศษของ$=เพียงแค่ว่ามันใช้ตัวเลขจำนวนเต็มเท่านั้น สามารถทำได้โดยใช้ตัวแปรสามัญ: $a=int$_[0]. intแต่ค่าใช้จ่ายที่สามไบต์เพิ่มเติมเพราะฟังก์ชั่น
Heiko Oberdiek

2

จูเลียอายุ 26 ปี

julia> f(n::Int)=n//1
f (generic function with 1 method)
julia> f(n)=int(-n)
f (generic function with 2 methods)
julia> f(f(4))
-4

ไม่ใช่การแข่งขันที่ยอดเยี่ยม แต่จูเลียนเป็นคนที่ต้องพึ่งพาการจัดส่งหลายครั้ง มันทำให้ na Rational ถ้ามันเป็น Int หรือ int ที่มีเครื่องหมายลบถ้ามันเป็นอย่างอื่น หนึ่งอาจวัตถุที่ว่านี้คือ 2 ฟังก์ชั่น nแต่จูเลียพิจารณานี้จะเป็นหนึ่งในฟังก์ชั่นที่มีสองวิธีการและมันจะเทียบเท่ากับการกำหนดหนึ่งฟังก์ชั่นที่มีถ้างบอยู่กับชนิดของ


ไม่ใช่สิ่งที่นักคณิตศาสตร์จะเรียกใช้ฟังก์ชัน: ใน Julia 3==3//1จะส่งคืนtrueแต่f(3//1)==f(3)กลับfalseมา
โอมาร์

2

ขนมหวาน , 20 18 ไบต์

ใช้ 3 -> 4 -> -3 -> -4 -> 3 เคล็ดลับ

~A2%{|m}1A0>{+|-}.

ในการเรียกใช้ให้ใช้สวิตช์ -i บนล่าม

ตัวอย่างของการเรียกซ้ำสองครั้ง:

$ candy -i 7 -e '~A2%{|m}1A0>{+|-}.'
program length: 18
>>> 8
$ candy -i 8 -e '~A2%{|m}1A0>{+|-}.'
program length: 18
>>> -7
$ candy -i -7 -e '~A2%{|m}1A0>{+|-}.'
program length: 18
>>> -8
$ candy -i -8 -e '~A2%{|m}1A0>{+|-}.'
program length: 18
>>> 7

แบบยาว:

peekA
pushA
digit2
mod          # even/odd
if
else
  negate     # negate even numbers
endif
digit1
pushA
digit0
greater      # positive/negative
if
  add        # add two numbers from stack (original stack value, and delta)
else
  sub        # diff two numbers from stack (original stack value, and delta)
endif
retSub

2

Dyalog APL 9 คะแนน

×-⍨⊢ׯ1*⊢

แหล่งที่มาคือ 9 ไบต์ยาวและมีสิทธิ์ได้รับโบนัส (ซึ่งไม่ได้ช่วยเลย) นอกจากนี้ยังใช้สูตรจากคำตอบ SO ด้านบน




1

Java, 113 ไบต์

วิธีการนั้นค่อนข้างง่าย มันจบลงด้วยไบต์มากกว่าที่ฉันคาดไว้ แต่อาจจะลงสนามได้เล็กน้อย

public class F{public static int f(int x){if(x<0)x+=-2147483647-++x;x+=1073741824;return x<0?-2147483647-++x:x;}

มันสร้างพื้น "พื้นที่" ที่แตกต่างกัน 4 ส่วนของ x โดยใช้ข้อเท็จจริงที่ว่า Java มีความสุขช่วยให้ตัวแปรล้อมรอบ ฉันต้องทำการแปลงที่ยุ่งยากสำหรับจำนวนลบซึ่งเป็นเหตุผลหลักที่ทำให้เรื่องนี้ใหญ่กว่าที่คาดการณ์ไว้

ใช้งานได้กับ x ทั้งหมดยกเว้น -2147483648


1

หมายเลขลำดับเดียวกัน (3, 4, -3, -4, 3 ... ) เหมือนกับคำตอบ golfscript แต่มีการใช้งานใน perl (42 chars หลังจากช่องว่างถูกถอดออก)

sub f{($_[0]%2?1:-1)*$_[0]+($_[0]<0?-1:1)}

ชัดเจนมากขึ้น:

sub f { ($_[0] % 2 ? $_[0] : -$_[0] ) + ( $_[0] < 0 ? -1 : 1 ) }

หรือชัดเจนยิ่งขึ้น:

sub f {
  my $n = shift;
  my $sign = $n >= 0 ? 1 : -1;
  # note that in perl $n % 2 is the same as int($n) % 2
  if( $n % 2 ) {
    # odd: add one to magnitude
    return $n + $sign
  } else {
    # even: subtract one from magnitude then invert
    return -($n - $sign)
  }
}

เอาท์พุท:

ski@anito:~/mysrc/.../acme$ echo 3 | perl -e 'sub f{($_[0]%2?1:-1)*$_[0] + ($_[0]<0?-1:1)}; my $x = <>; for(0..10) { print "$_: $x\n"; $x = f($x); }'
0: 3
1: 4
2: -3
3: -4
4: 3
5: 4
6: -3
7: -4
8: 3
9: 4
10: -3

ด้านบนใช้งานได้กับจำนวนเต็ม: ski @ anito: ~ / mysrc /.../ acme $ echo 1.1234 | perl -e 'sub f {($ _ [0]% 2? 1: -1) * $ _ [0] + ($ _ [0] <0? -1: 1)}; $ x = <> ของฉัน; สำหรับ (0..4) {พิมพ์ "$ _: $ x \ n"; $ x = f ($ x); } '0: 1.1234 1: 2.1234 2: -1.1234 3: -2.1234 4: 1.1234
skibrianski


1

Matlab, 26 ตัวอักษร

f=@(n) (n<0)-(n<0)-n*(-1)^n

2
นี่ไม่ใช่คำตอบที่ถูกต้องเนื่องจากโดเมนและโคโดเมนของฟังก์ชันต้องไม่ซับซ้อน
Wrzlprmft

โอ้ฉันขอโทษ ... ฉันเพียงแค่อ่านชื่อเรื่องและไม่ได้ว่าระวัง ... ดูกันเถอะว่าฉันสามารถแก้ไขได้บ้าง
BLA

1

C ++ - 63 55.8

นี่คือลักษณะของรหัส:

int f(int n){return (n&45056?n^45056:n|45056)*(n&45056?-1:1);}

ไม่ทำงานกับจำนวนเต็มที่มีไบต์ที่สี่เท่ากับ 0xB เนื่องจากใช้ค่านั้นเพื่อติดตามการผ่าน มิฉะนั้นทำงานกับสมาชิกของ Z ใด ๆ รวมถึงศูนย์


คุณอธิบายได้ไหม ในการตรวจสอบครั้งแรกดูเหมือนว่าคุณยังคงมีการตอบโต้การโทรfด้วยตัวแปรคง แต่แล้วจุดประสงค์sqrtคืออะไร?
ardnew

ฉันดูเหมือนจะเข้าใจผิดคำถาม; คิดว่าตัวแปรแบบสแตติกนั้นโอเคเนื่องจาก C ++ เป็นภาษาแบบสแตติก แต่ฉันจะแก้ไขโค้ด ไม่อย่างนั้นฉันก็ไม่รู้ว่าทำไมฉันถึงต้องใช้sqrtเพราะมันถูกปัดเศษลงด้วยการคัดเลือกนักแสดง ฉันจะ refactor มันเพื่อให้ทำงานโดยไม่มีตัวแปรคงที่
Darkgamma

ฉันไม่รู้ว่าคุณได้55.8มาจากไหนแต่รหัสปัจจุบันของคุณยาว 62 ไบต์ แก้ไข:ไม่เป็นไรฉันไม่ได้อ่านคำถามอย่างถูกต้อง
nyuszika7h

ข้อ จำกัด ที่ไบต์ที่สี่ไม่สามารถเท่ากับ 0xB ได้ทำให้นี่ไม่ใช่คำตอบที่ถูกต้องสำหรับความท้าทายซึ่งต้องใช้จำนวนเต็ม (อย่างน้อย) ทั้งหมด
pppery

1

อัปเดตด้วยฟังก์ชั่นที่จัดทำโดย Synthetica (เห็นได้ชัดว่าคนที่ควรได้รับเครดิตในตอนนี้)

ภาษา: Python

จำนวนตัวอักษร: 41 รวมถึงช่องว่าง

f=lambda x:-float(x) if str(x)==x else`x`

โปรดระบุชื่อภาษาที่คุณใช้ในการระบุจำนวนอักขระด้วย
ProgramFOX

ฉันชอบวิธีการนี้ทำงานร่วมกับไม่ใช่จำนวนเต็ม ทำได้ดี. :)
cjfaure

f=lambda x:-float(x) if str(x)==x else`x`ค่อนข้างสั้น: 41 รวมถึง whitespace
ɐɔıʇǝɥʇuʎs

ขอบคุณ Synthetica ฉันไม่ทราบเกี่ยวกับเคล็ดลับ Backticks! : D
HolySquirrel

ในจำนวนเต็มfกลับสตริง; สเปคบอกว่ามันจะต้องส่งกลับจำนวนตรรกยะ
โอมาร์

1

Prolog ขนาด 36 ไบต์

รหัส:

X*Y:-X//1=:=X,Y is 0.5+X;Y is 0.5-X.

อธิบาย:

Dyadic predicate which converts integers to floats and floats back to negated integers.

ตัวอย่าง:

10*X.
X = 10.5

10*Y,Y*X.
X = -10,
Y = 10.5


1

Mouse-2002 , 21 19 12 ไบต์

$A1%[1%_|1%]

กำหนดฟังก์ชั่นA; เรียกว่าชอบ#A,#A,?;;(ซึ่งจะรอให้ผู้ใช้ป้อนหมายเลขใด ๆ ) หรืออีกวิธีหนึ่งเรียกว่าเหมือน#A,#A,n;;ที่nเป็นจำนวนใด ๆ


1

จูเลีย, 21

f(x)=(1-2(1>x>-1))/2x

แล้วก็

julia> f(f(12//1))
-12//1

p // q เป็นตัวเลขที่แท้จริงของ julia สัญกรณ์ตัวเลข

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.