ภารกิจสกัดเสียงกระเพื่อม


19

ในภาษาสไตล์เสียงกระเพื่อมรายการมักจะถูกกำหนดเช่นนี้:

(list 1 2 3)

สำหรับจุดประสงค์ของการท้าทายรายการทั้งหมดจะมีจำนวนเต็มบวกหรือรายการอื่น ๆ เท่านั้น เราจะไม่ใส่listคำหลักในตอนเริ่มต้นดังนั้นรายการจะมีลักษณะดังนี้:

(1 2 3)

carเราจะได้รับองค์ประกอบแรกของรายการโดยใช้ ตัวอย่างเช่น:

(car (1 2 3))
==> 1

และเราสามารถรับรายการต้นฉบับโดยลบองค์ประกอบแรกด้วยcdr:

(cdr (1 2 3))
==> (2 3)

สำคัญ: cdrจะส่งคืนรายการเสมอแม้ว่ารายการนั้นจะมีองค์ประกอบเดียว:

(cdr (1 2))
==> (2)
(car (cdr (1 2)))
==> 2

รายการสามารถอยู่ในรายการอื่น ๆ :

(cdr (1 2 3 (4 5 6)))
==> (2 3 (4 5 6))

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

ตัวอย่าง:

การป้อนข้อมูล: (6 1 3) 3

เอาท์พุท: (car (cdr (cdr l)))

การป้อนข้อมูล: (4 5 (1 2 (7) 9 (10 8 14))) 8

เอาท์พุท: (car (cdr (car (cdr (cdr (cdr (cdr (car (cdr (cdr l))))))))))

การป้อนข้อมูล: (1 12 1992) 1

เอาท์พุท: (car l)


เราสามารถนำเข้าด้วยจำนวนเต็มก่อนและรายการที่สองได้หรือไม่?
Martin Ender

@ MartinBüttnerแน่นอน
absinthe

สิ่งที่เกี่ยวกับ(1 2 3) 16เราจะกลับมา()?
coredump

@coredump เป็นคำถามที่ดี คุณสามารถสมมติว่าจำนวนเต็มเป้าหมายจะอยู่ในนิพจน์เสมอดังนั้นกรณีเช่น(1 2 3) 16นี้จะไม่ปรากฏขึ้น
absinthe

เราสามารถรับอินพุตได้สองอันอันหนึ่งสำหรับลิสต์และอีกอันสำหรับจำนวนเต็ม?
Blackhole

คำตอบ:


1

CJam, 59

q"()""[]"er~{:AL>{0jA1<e_-_A(?j'l/"(car l)"@{2'dt}&*}"l"?}j

ลองออนไลน์

คำอธิบาย:

q                 read the input
"()""[]"er        replace parentheses with square brackets
~                 evaluate the string, pushing an array and a number
{…}j              calculate with memoized recursion using the array as the argument
                   and the number as the memozied value for argument 0
  :A              store the argument in A
  L>              practically, check if A is an array
                   if A is a (non-empty) array, compare with an empty array
                   (result 1, true)
                   if A is a number, slice the empty array from that position
                   (result [], false)
    {…}           if A is an array
      0j          get the memoized value for 0 (the number to search)
      A1<         slice A keeping only its first element
      e_          flatten array
      -           set difference - true iff the number was not in the array
      _           duplicate the result (this is the car/cdr indicator)
      A(          uncons A from left, resulting in the "cdr" followed by the "car"
      ?           choose the cdr if the number was not in the flattened first item,
                   else choose the car
      j           call the block recursively with the chosen value as the argument
      'l/         split the result around the 'l' character
      "(car l)"   push this string
      @           bring up the car/cdr indicator
      {…}&        if true (indicating cdr)
        2'dt      set the character in position 2 to 'd'
      *           join the split pieces using the resulting string as a separator
    "l"           else (if A is not an array) just push "l"
                   (we know that when we get to a number, it is the right number)
    ?             end if

10

เสียงกระเพื่อมสามัญ, 99

โซลูชันขนาด 99 ไบต์ต่อไปนี้เป็นคำตอบที่ดีของSchemeคำตอบโครงการ

(defun g(l n &optional(o'l))(if(eql n l)o(and(consp l)(or(g(car l)n`(car,o))(g(cdr l)n`(cdr,o))))))

ฉันพยายามใช้ประโยชน์จากpositionและposition-ifมันกลับกลายเป็นว่าไม่กะทัดรัดเท่าที่ฉันจะชอบ (209 ไบต์):

(lambda(L x &aux(p'l))(labels((f(S &aux e)(cons(or(position x S)(position-if(lambda(y)(if(consp y)(setf e(f y))))S)(return-from f()))e)))(dolist(o(print(f L))p)(dotimes(i o)(setf p`(cdr,p)))(setf p`(car,p)))))

ขยาย

(lambda
  (l x &aux (p 'l))
  (labels ((f (s &aux e)
             (cons
              (or (position x s)
                  (position-if
                   (lambda (y)
                     (if (consp y)
                         (setf e (f y))))
                   s)
                  (return-from f nil))
              e)))
    (dolist (o (print (f l)) p)
      (dotimes (i o) (setf p `(cdr ,p)))
      (setf p `(car ,p)))))

ตัวอย่าง

(funcall *fun* '(4 5 (1 2 (7) 9 (10 8 14))) 14)

รายการถูกยกมา แต่ถ้าคุณต้องการฉันสามารถใช้แมโคร ค่าที่ส่งคืนคือ[1] :

(CAR (CDR (CDR (CAR (CDR (CDR (CDR (CDR (CAR (CDR (CDR L)))))))))))

สำหรับการทดสอบฉันใช้เพื่อสร้างรูปแลมบ์ดาที่ lเป็นตัวแปร:

(LAMBDA (#:G854) (CAR (CDR (CDR (CAR (CDR (CDR (CDR (CDR (CAR (CDR (CDR #:G854))))))))))))

การเรียกสิ่งนี้ด้วยรายการดั้งเดิมจะส่งคืน 14


[1] (caddar (cddddr (caddr l)))ก็ดีเช่นกัน


2
คุณตอบคำถามเกี่ยวกับเสียงกระเพื่อมกับเสียงกระเพื่อม! มันเป็นเสียงกระเพื่อม!
DanTheMan

4
@DanTheMan เสียงกระเพื่อม-ception สวยมากสิ่งที่กำหนดชัด ;-)
coredump

9

Retina , 170 142 125 115 114 87 84 83 75 73 70 69 68 67 ไบต์

ใช่น้อยกว่า 50% จากมากกว่า 100 ไบต์จากการลองครั้งแรกของฉัน :)

\b(.+)\b.* \1$
(
^.
l
\(
a
+`a *\)|\d


d
+`(.*[l)])(\w)
(c$2r $1)

ในการเรียกใช้รหัสจากไฟล์เดียวให้ใช้ -sตั้งค่าสถานะ

ฉันยังไม่มั่นใจว่าสิ่งนี้เหมาะสมที่สุด ... ฉันจะไม่มีเวลามากในอีกไม่กี่วันข้างหน้าฉันจะเพิ่มคำอธิบายในที่สุด


5

Pyth, 62 ไบต์

JvXz"() ,][")u?qJQG&=J?K}Quu+GHNY<J1)hJtJ++XWK"(cdr "\d\aG\)\l

ลองใช้ออนไลน์: การสาธิตหรือชุดทดสอบ

คำอธิบาย:

บิตแรกJvXz"() ,][")แทนที่ chars "() "ด้วย chars "[],"ในสตริงอินพุตซึ่งลงท้ายด้วยการแสดงรายการ Python-style list Jผมประเมินและเก็บไว้ใน

แล้วฉันจะลดสตริงกับG = "l" u...\lฉันใช้ฟังก์ชันด้านใน...ซ้ำ ๆGจนกระทั่งค่าGไม่เปลี่ยนแปลงอีกต่อไปแล้วพิมพ์Gไม่เปลี่ยนแปลงอีกต่อไปแล้วพิมพ์

ฟังก์ชั่นด้านในทำสิ่งต่อไปนี้: หากJมีค่าเท่ากับหมายเลขอินพุตอยู่แล้วไม่ต้องแก้ไขG( ?qJQG) มิฉะนั้นฉันจะเรียบรายการJ[:1]และตรวจสอบว่าหมายเลขอินพุตอยู่ในรายการนั้นและบันทึกลงในตัวแปรK( K}Quu+GHNY<J1)) โปรดสังเกตว่า Pyth ไม่มีตัวดำเนินการแบนดังนั้นจึงใช้เวลาค่อนข้างน้อย หากKเป็นจริงมากกว่าที่ฉันอัปเดต J ด้วยJ[0]มิฉะนั้นด้วยJ[1:]( =J?KhJtJ) แล้วฉันแทนที่Gด้วย"(cdr G)"และแทนที่ถ้าเป็นความจริง ( )daK++XWK"(cdr "\d\aG\)



1

PHP - 177 ไบต์

ฉันได้เพิ่มบรรทัดใหม่สำหรับการอ่าน:

function f($a,$o,$n){foreach($a as$v){if($n===$v||$s=f($v,$o,$n))return
'(car '.($s?:$o).')';$o="(cdr $o)";}}function l($s,$n){echo f(eval(strtr
("return$s;",'() ','[],')),l,$n);}

นี่คือรุ่นที่ไม่ได้แต่งแต้ม:

function extractPhp($list, $output, $number)
{
    foreach ($list as $value)
    {
        if (is_int($value))
        {
            if ($value === $number) {
                return '(car '. $output .')';
            }
        }
        else
        {
            $subOutput = extractPhp($value, $output, $number);
            if ($subOutput !== null) {
                return '(car '. $subOutput .')';
            }
        }

        $output = '(cdr '. $output .')';
    }
}

function extractLisp($stringList, $number)
{
    $phpCode = 'return '. strtr($stringList, '() ','[],') .';';
    $list = eval($phpCode);
    echo extractPhp($list, 'l', $number);
}

1

Haskell, 190 188 ไบต์

l "(4 5 (1 2 (7) 9 (10 8 14)))" 8

ประเมินให้

"(car (cdr (car (cdr (cdr (cdr (cdr (car (cdr (cdr l))))))))))"

l(h:s)n=c$i(show n)s""""
i n(h:s)t l|h>'/'&&h<':'=i n s(t++[h])l|t==n='a':l|h=='('=j$'a':l|h==')'=j$tail$dropWhile(=='d')l|0<1=j$'d':l where j=i n s""
c[]="l"
c(h:s)="(c"++h:"r "++c s++")"

1
คุณสามารถเปลี่ยน(และcใช้ฟังก์ชันcเป็นสตริงได้:c(h:s)="(c"++h:...
nimi

ว้าวไม่คิดว่าจะhเป็น Char!
Leif Willerts

0

เสียงกระเพื่อมสามัญ, 168 155 ไบต์

บางสิ่งที่วนเวียนมาซ้ำซากจำเจ

(lambda(l e)(labels((r(l o)(setf a(car l)d(cdr l)x`(car,o)y`(cdr,o))(if(equal e a)x(if(atom a)(r d y)(if(find e l)(r d y)(if d(r d y)(r a x)))))))(r l'l)))

พิมพ์สวย:

(lambda (l e)
  (labels ((r (l o)
             (setf a (car l) d (cdr l)
                   x `(car ,o) y `(cdr ,o))
             (if (equal e a) x
                 (if (atom a)
                     (r d y)
                     (if (find e l)
                         (r d y)
                         (if d
                             (r d y)
                             (r a x)))))))
    (r l 'l)))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.