หมุนกล้อง; บันทึกนักบินอวกาศ


23

หมายเหตุ: สปอยเลอร์เล็กน้อยสำหรับชาวอังคารกำลังท้าทาย อ่านล่วงหน้าด้วยความระมัดระวัง


อังคารเป็นนิยายวิทยาศาสตร์นวนิยายเกี่ยวกับมนุษย์อวกาศและนักพฤกษศาสตร์วิสามัญมาร์คมาร์กนีย์ผู้ซึ่งติดอยู่บนดาวอังคารโดยบังเอิญ เมื่อถึงจุดหนึ่งในหนังสือมาร์คพยายามสื่อสารกับ NASA แต่วิธีการสื่อสารเดียวที่พวกเขามีคือกล้อง Mark ส่งข้อความโดยการเขียนลงบนบัตรดัชนีและเนื่องจาก NASA สามารถหมุนกล้องได้ 360 องศา NASA จึงส่งคำตอบกลับโดยหันกล้องไปที่การ์ดที่มีป้ายกำกับว่า "ใช่" หรือ "ไม่"

เนื่องจากข้อมูลเพียงอย่างเดียวที่นาซ่าสามารถส่งได้คือทิศทางที่กล้องหันเข้าหามาร์คจึงมาพร้อมกับระบบที่พวกเขาสามารถชี้ไปที่การ์ดที่มีตัวอักษรตัวอักษรเพื่อพิมพ์ข้อความ แต่การใช้ตัวอักษร 'az' จะไม่สามารถทำได้ หากต้องการอ้างอิงหนังสือ (จากคำตอบนี้มีให้ที่ scifi.se):

เราจะต้องพูดเร็วกว่าใช่ / ไม่ใช่คำถามทุกครึ่งชั่วโมง กล้องสามารถหมุนได้ 360 องศาและฉันมีชิ้นส่วนเสาอากาศมากมาย ใช้เวลาในการทำตัวอักษร แต่ฉันไม่สามารถใช้ตัวอักษร A ถึง Z. ตัวอักษรยี่สิบหกบวกบัตรคำถามของฉันจะเป็นยี่สิบเจ็ดบัตรรอบแลนเดอร์ แต่ละอันจะได้ส่วนโค้งที่ 13 องศาเท่านั้น แม้ว่า JPL จะชี้กล้องอย่างสมบูรณ์แบบ แต่ก็มีโอกาสดีที่ฉันจะไม่รู้ว่าตัวอักษรนั้นหมายถึงอะไร

ดังนั้นฉันจะต้องใช้ ASCII นั่นเป็นวิธีที่คอมพิวเตอร์จัดการกับตัวละคร ตัวละครแต่ละตัวมีรหัสตัวเลขระหว่าง 0 ถึง 255 ค่าระหว่าง 0 ถึง 255 สามารถแสดงเป็นเลขฐานสิบหก 2 หลัก โดยให้เลขฐานสิบหกแก่ฉันพวกเขาสามารถส่งอักขระใด ๆ ที่พวกเขาชอบรวมถึงตัวเลขเครื่องหมายวรรคตอนและอื่น ๆ

...

ดังนั้นฉันจะทำบัตรสำหรับ 0 ถึง 9 และ A ถึง F ที่ทำให้ 16 บัตรเพื่อวางรอบกล้องรวมทั้งการ์ดคำถาม เจ็ดใบมีความหมายมากกว่า 21 องศาในแต่ละใบ ง่ายต่อการจัดการกับ

เป้าหมายของคุณในวันนี้ในฐานะหนึ่งในวิศวกรซอฟต์แวร์ชั้นนำของ NASA คือการเขียนโปรแกรมเพื่อเข้ารหัสมุมต่าง ๆ ของกล้อง ไพ่เจ็ดใบที่มาร์คมีให้สำหรับคุณที่จุดคือ (ตามลำดับ):

?0123456789ABCDEF

และแต่ละบัตรเหล่านี้คือ 21 องศาออกจากกันเพื่อที่จะหมุนกล้องจาก?ไป0คุณควรหมุนกล้อง 21 องศาและ2จะ1เป็น -21 องศา (ไม่ใช่21 อย่างแน่นอนแต่เราจะปัดให้เรียบง่ายขึ้น) ค่านี้ล้อมรอบดังนั้นจากFไปถึง3คือ 105 องศา (5 รอบ 5 * 21 = 105) ซึ่งมีประสิทธิภาพมากกว่าการไป -252 เนื่องจากกล้องไม่ต้องเคลื่อนที่ไปไกล

นี่คือสิ่งที่โปรแกรมหรือฟังก์ชั่นของคุณต้องทำ

  1. ใช้สตริงเป็นอินพุต เราจะเรียกสายนี้s เพื่อให้ง่ายเราจะบอกว่าการป้อนข้อมูลจะสามารถพิมพ์ได้ ASCII เท่านั้น สำหรับตัวอย่างของเราสมมุติว่าอินพุตนั้นSTATUS

  2. แปลงอักขระแต่ละตัวให้เป็นตัวแทนเลขฐานสิบหก สิ่งนี้จะแปลงSTATUSเป็น53 54 41 54 55 53ไป

  3. พิมพ์หรือย้อนกลับในระดับที่ต่อเนื่องหันกล้องจะต้องทำเพื่อที่จะชี้ไปที่การ์ดแต่ละใบและกลับไปที่ "บัตรคำถาม" สำหรับตัวอย่างของเราสิ่งนี้จะเป็น:

    6  * 21 = 126   (?-5)
    -2 * 21 = -42   (5-3)
    2  * 21 = 42    (3-5)
    -1 * 21 = -21   (5-4)
    0  * 21 = 0     (4-4)
    -3 * 21 = -63   (4-1)
    4  * 21 = 84    (1-5)
    -1 * 21 = -21   (5-4)
    1  * 21 = 21    (4-4)
    0  * 21 = 0     (5-5)
    0  * 21 = 0     (5-5)
    -2 * 21 = -42   (5-3)
    -4 * 21 = -84   (3-?)
    

    หรือในรูปแบบอาร์เรย์:

    [126, -42, 42, -21, 0, -63, 84, -21, 21, 0, 0, -42, -84]
    

โปรดทราบว่าคุณจะต้องหมุนน้อยที่สุดเท่าที่จะทำได้ ดังนั้นถ้าอินพุทคือNOซึ่งก็คือ4E 4Fคุณควรเอาท์พุท:

5    * 21 = 105
-7   * 21 = -147
7    * 21 = 147
-6   * 21 = -126
1    * 21 = 21

ค่อนข้างมากกว่า:

 5   * 21 = 105
 10  * 21 = 210
 -10 * 21 = -210
 11  * 21 = 231
 -16 * 21 = -336

นี่คือตัวอย่างการทำงานเพิ่มเติม:

Input: CROPS?
ASCII: 43 52 4F 50 53 3F
Worked Example:

5  * 21 = 105
-1 * 21 = -21
2  * 21 = 42
-3 * 21 = -63
2  * 21 = 42
-6 * 21 = -126
7  * 21 = 147
-5 * 21 = -105
5  * 21 = 105
-2 * 21 = -42
0  * 21 = 0
-5  * 21 = -105
1 * 21 = 21

Result: [105 -21 42 -63 42 -126 147 -105 105 -42 0 -105 21]


Input: DDD
ASCII: 44 44 44
Worked Example:

5   * 21 = 105
0   * 21 = 0
0   * 21 = 0
0   * 21 = 0
0   * 21 = 0
0   * 21 = 0
-5  * 21 = -105

Result: [105, 0, 0, 0, 0, 0, -105]


Input: Hello world!
ASCII: 48 65 6c 6c 6f 20 77 6f 72 6c 64 21
Worked example:

5   * 21 = 105
4   * 21 = 84
-2  * 21 = -42
-1  * 21 = -21
1   * 21 = 21
6   * 21 = 126
-6  * 21 = -126
6   * 21 = 126
-6  * 21 = -126
-8  * 21 = -168
4   * 21 = 84
-2  * 21 = -42
7   * 21 = 147
0   * 21 = 0
-1  * 21 = -21
-8  * 21 = -168
-8  * 21 = -168
-5  * 21 = -105
4   * 21 = 84
6   * 21 = 126
-6  * 21 = -126
-2  * 21 = -42
-2  * 21 = -42
-1  * 21 = -21
-2  * 21 = -42

Result: [105 84 -42 -21 21 126 -126 126 -126 -168 84 -42 147 0 -21 -168 -168 -105 84 126 -126 -42 -42 -21 -42]

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


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

คำตอบ:


5

JavaScript (ES6), 103 99 ไบต์

s=>[...s.replace(/./g,c=>c.charCodeAt().toString(16)),10].map(n=>((24-p-~(p='0x'+n))%17-8)*21,p=-1)

กรณีทดสอบ


จะใช้งานได้ไหม s.replace(/./g,->[...s].map(
ลุค

@Luke Nope เพราะเราต้องแยกตัวเลขฐานสิบหกออก ...s.replace(/./g,ให้เช่น"4","8","6","5","6","c"...ในขณะที่ ...[...s.map(จะให้"48","65","6c",...
ETHproductions

4

C, 212 202 199 187 bytes

บันทึก 3 ไบต์ด้วย @KritixiLithos!

i;f(a,b){i=abs(a-b);i=8>i?i:17-i;i=a<b&a>b-8?i:a<b&a<b-8?-i:b<a&b>a-8?-i:i;i*=21;}v;g(char*s){for(v=0;*s;s+=v++%2)printf("%d ",v?v%2?f(*s%16,s[1]?s[1]/16:-1):f(*s/16,*s%16):f(-1,*s/16));}

ลองออนไลน์!


1
ฉันคิดว่าคุณสามารถทำได้8>i?i:17-iแทน17-i>i?...
Kritixi Lithos

@KritixiLithos yup ขอบคุณ
betseg

3

Python, 187 178 ไบต์

def g(x):w,z=map('?0123456789abcdef'.index,x);d=w-z;return min(d,d+17*(d<=0 or -1),key=abs)*21
def f(s):s=''.join(map('{:2x}'.format,s.encode()));return[*map(g,zip(s+'?','?'+s))]

กรณีทดสอบ

for k in ['STATUS', 'NO', 'CROPS?', 'DDD', 'Hello world!']:
    print('Input:  {}\nOutput: {}'.format(k, f(k)))


1

เยลลี่ , 21 19 ไบต์

Ob⁴F-;;-I+8%17_8×21

ลองออนไลน์!

อย่างไร?

Ob⁴F-;;-I+8%17_8×21 - Main link: string s        e.g. 'e.g.'
O                   - cast to ordinals            [101,     46,       103,      46]
 b                  - convert to base
  ⁴                 -     16                   [[6,   5], [2,  14], [6,   7], [2,  14]]
   F                - flatten                   [6,   5,   2,  14,   6,   7,   2,  14]
    -;              - -1 concatenate      [-1,   6,   5,   2,  14,   6,   7,   2,  14]
      ;-            - concatenate -1      [-1,   6,   5,   2,  14,   6,   7,   2,  14,  -1]
        I           - increments            [  7,  -1,  -3,  12,  -8,   1,  -5,  12, -15]
         +8         - add 8                 [ 15,   7,   5,  20,   0,   9,   3,  20,  -7]
           %17      - mod 17                [ 15,   7,   5,   3,   0,   9,   3,   3,  10]
              _8    - subtract 8            [  7,  -1,  -3,  -5,  -8,   1,  -5,  -5,   2]
                ×21 - multiply by 21        [147, -21, -63,-105,-168,  21,-105,-105,  42]

1

โอห์ม , 20 19 ไบต์ (CP437) ที่ไม่ใช่การแข่งขัน

แก้ไข : บันทึก 1 ไบต์โดยการเปลี่ยนบล็อกแผนที่เป็นแผนที่องค์ประกอบเดียวซ้ำแล้วซ้ำอีก

อาจจะค่อนข้างสั้นลงเล็กน้อยถ้าฉันมีเวกเตอร์โดยนัย

`»x»}{»úΓXΓHδ▓_~21*

คำอธิบาย:

`»x»}{»úΓXΓHδ▓_~21*    Main wire, arguments: s

`»x                    Convert char codes of s to hex
   »}                  Split digit pairs
     {                 Flatten
      »ú               Convert digits back to base 10
        ΓXΓH           Append and prepend with -1
            δ          Get deltas between each element of array
             ▓         Map array over...
              _~21*      Negate, multiply by 21

0

PHP, 125 116 ไบต์:

function m($i){static$a;$a+=$d=($i-$a+10)%17-9;echo$d*21,"
";}for(;$c=ord($argv[1][$i++]);m($c%16))m($c/16|0);m(-1);

ทำให้พังถล่ม

function m($i)              // function to turn camera:
{
    static$a;                   // remember angle
    $a+=                        // add delta to angle
    $d=($i-$a+10)%17-9;         // delta: target=nibble value+1-current angle
                                // add 9, modulo 17, -9 -> shortest movement
    echo$d*21,"\n";                 // print delta * 21 and a linebreak
}
for(;$c=ord($argv[1][$i++]);// loop through input characters
    m($c%16))                   // 2. move to low nibble value
    m($c/16|0)                  // 1. move to high nibble value
;
m(-1);                      // move back to "?"

แน่นอน21มันไม่ถูกต้องสวยและอาจล้มเหลวสำหรับสตริงยาวกว่า 14 ตัวอักษร; แต่หลังจากนั้น ... 360/17จะยาวสี่ไบต์

ทางเลือกอื่นก็คือการเชื่อมต่อตัวชี้เลเซอร์เข้ากับกล้อง
เราสามารถใช้ ASCII ที่พิมพ์ได้ทั้งหมดและการ์ด "คำถาม" ที่ 3.75 องศาแต่ละอัน

อีกทางเลือกหนึ่ง: ใช้ 16 ใบ (ที่ 22.5 องศา) ด้วย 6 ตัวอักษร:
ใช้ T9 บางประเภทและเราสามารถตัดแทะสูงได้ ;)

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