ระบุต้นไม้ไบนารีทั้งหมดด้วยโหนด n


10

รับจำนวนเต็ม n ระบุต้นไม้ไบนารีเต็มที่เป็นไปได้ทั้งหมดที่มีโหนดภายใน (ต้นไม้ไบนารีเต็มมีลูก 2 คนในทุกโหนดภายใน) โครงสร้างต้นไม้ควรถูกส่งออกเป็น traversal ที่สั่งซื้อล่วงหน้าของต้นไม้โดยที่ 1 หมายถึงโหนดภายในและ 0 หมายถึงโหนดภายนอก (Null)

นี่คือตัวอย่างสำหรับสองสามคนแรก:

0:
0

1:
100

2:
11000
10100

3:
1110000
1101000
1100100
1011000
1010100

นี่คือรหัสกอล์ฟที่มีรางวัลน้อยที่สุดสำหรับตัวละคร ต้นไม้ควรจะถูกส่งออกหนึ่งต่อบรรทัดเพื่อ stdout โปรแกรมควรอ่าน n จาก commandline หรือ stdin


ฉันกำลังคิดเกี่ยวกับปัญหานั้นเมื่อฉันพยายามสร้างระบบการเขียนที่เหมือนเขาวงกต
Ming-Tang

กำหนดเวลามาตรฐานคืออะไรก่อนที่จะประกาศวิธีแก้ปัญหา?
Kyle Butt

จะมีความสนใจในการเปลี่ยนแปลงเล็กน้อยของปัญหานี้ซึ่งจะต้องสั่งออกและสตรีมมิ่ง?
Kyle Butt

@Kyle Butt เพียงความเห็นของฉัน แต่ฉันไม่คิดว่าฉันจะสนใจ สำหรับฉันส่วนหนึ่งของความสนุกกับปัญหาเหล่านี้คือการลองใช้วิธีทางเลือกและการสั่งซื้อที่แน่นอนอาจ จำกัด จำนวนอัลกอริทึมที่ใช้การได้
migimaru

คำตอบ:


3

Perl - 125 79 ตัวอักษร

การนับรวม 4 ตัวอักษรสำหรับ-lnตัวเลือก "" ใช้ n จาก stdin

วิธีการที่สร้างสรรค์ใหม่:

@a=0;map{%a=();map{$a{"$`100$'"}=1while/0/g;}@a;@a=keys%a}1..$_;print for@a

สร้างโซลูชันสำหรับ n โดยการแทนที่โหนดภายในใหม่ ("100") สำหรับแต่ละใบไม้ ("0") ตามลำดับในแต่ละต้นไม้จากโซลูชันสำหรับ n-1

(ฉันเป็นหนี้แนวคิดนี้กับโซลูชันของผู้อื่นที่ใช้โหนดภายในเพื่อแทนที่ [100-> 0] เพื่อทดแทนการตรวจสอบสตริงที่สร้างขึ้นตามลำดับและฉันเชื่อว่าฉันเห็น - หลังจากเขียนคำตอบของฉันตามแนวคิดนั้น - เช่นเดียวกัน 0- > 100 วิธีการก่อสร้างในการแก้ไขระดับกลางของใครบางคน)

วิธีการเรียกซ้ำก่อนหน้านี้:

sub t{my$n=shift;if($n){--$n;for$R(0..$n){for$r(t($R)){for$l(t($n-$R)){push@_,"1$l$r"}}}}else{push@_,"0"}@_}print for t$_

แบบไม่โต้ตอบซ้ำ:

sub tree {
  my ($n) = @_;
  my @result = ();
  if ( $n ) {
    for $right_count ( 0 .. $n-1 ) {
      for $right ( tree( $right_count ) ) {
        for $left ( tree( ($n-1) - $right_count ) ) {
          push @result, "1$left$right";
        }
      }
    }
  }
  else {
    push @result, "0";
  }
  return @result;
}
foreach $tree ( tree($_) ) {
  print $tree;
}

2

PHP (142) (138) (134) (113)

ทำงานจากบรรทัดคำสั่งเช่น "php golf.php 1" เอาต์พุต "100"

แก้ไข: ตัดตัวละคร 4 ตัวด้วยวิธีทางเลือกสร้างสตริงจาก 0 แทนที่จะเรียกซ้ำจาก $ n ใช้ PHP 5.3 สำหรับผู้ประกอบการที่สั้นลง มิฉะนั้นจะต้องใช้อักขระเพิ่มอีก 2 ตัว

แก้ไข 2: บันทึกอีก 4 ตัวอักษรพร้อมการเปลี่ยนแปลงลูปบางอย่าง

แก้ไข 3: ฉันลองใช้วิธีอื่นและในที่สุดฉันก็ได้วิธีต่ำกว่าวิธีเดิม

ต้นไม้ทั้งหมดถือได้ว่าเป็นการแทนเลขฐานสองของจำนวนเต็มระหว่าง 4 ^ n (หรือ 0 เมื่อ n = 0) และ 2 * 4 ^ n ฟังก์ชั่นนี้วนซ้ำในช่วงนั้นและรับสตริงไบนารี่ของแต่ละหมายเลขจากนั้นจะลดลงซ้ำ ๆ โดยแทนที่ "100" ด้วย "0" หากสตริงสุดท้ายคือ "0" แสดงว่าเป็นแผนผังที่ถูกต้องดังนั้นเอาต์พุต

for($i=$p=pow(4,$argv[1])-1;$i<=2*$p;){$s=$d=decbin($i++);while($o!=$s=str_replace(100,0,$o=$s));echo$s?:"$d\n";}

2

Ruby, 99 94 92 89 87 ตัวละคร

(n=4**gets.to_i).times{|i|s=(n+i-1).to_s 2;t=s*1;0while s.sub!'100',?0;puts t if s==?0}

อินพุตถูกอ่านจาก stdin

> echo 2 | ruby binary_trees.rb
10100
11000

แก้ไข 1:เปลี่ยน IO (ดูความคิดเห็นของ Lowjacker)

b=->n{n==0?[?0]:(k=[];n.times{|z|b[z].product(b[n-1-z]){|l|k<<=?1+l*''}};k)}
puts b[gets.to_i]

แก้ไข 2:อัลกอริทึมที่เปลี่ยนแปลง

b=->n{n==0?[?0]:(k=[];b[n-1].map{|s|s.gsub(/0/){k<<=$`+'100'+$'}};k.uniq)}
puts b[gets.to_i]

แก้ไข 3:ตอนนี้เวอร์ชันใช้แนวทางที่สาม (โดยใช้แนวคิดของ migimaru)

แก้ไข 4:อีกสองตัวละคร ขอบคุณ migimaru


มันจะสั้นกว่าอักขระหนึ่งตัวเพื่อรับอินพุตจาก stdin
Lowjacker

นอกจากนี้คุณไม่จำเป็นต้อง*?\nเพราะputsพิมพ์องค์ประกอบของอาร์เรย์ในแต่ละบรรทัดของตัวเอง
Lowjacker

@ Lowjacker ขอบคุณ
Howard

ฉันเพิ่งเริ่มเรียนรู้ทับทิม แต่ฉันคิดว่าคุณสามารถบันทึกตัวละครโดยใช้ 0 ในขณะที่ {} แทนในขณะที่ อย่างน้อยก็ทำงานได้ใน NetBeans
migimaru

นอกจากนี้ย่อย! ก็เพียงพอแล้วที่นี่แทนที่จะเป็น gsub! ดังนั้นนั่นคือตัวละครอีกตัวที่คุณสามารถช่วยได้
migimaru

1

ทับทิม 1.9 (80) (79)

การใช้วิธีการที่ไม่ซ้ำเกิดซ้ำซึ่งใช้โดย DCharness

แก้ไข: บันทึก 1 ตัวอักษร

s=*?0;gets.to_i.times{s.map!{|x|x.gsub(?0).map{$`+'100'+$'}}.flatten!}
puts s&s

0

Haskell 122 ตัวอักษร

main=do n<-readLn;mapM putStrLn$g n n
g 0 0=[['0']]
g u r|r<u||u<0=[]
g u r=do s<-[1,0];map((toEnum$s+48):)$g(u-s)(r-1+s)

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

module BinTreeEnum where

import Data.List
import Data.Monoid

data TStruct = NonEmpty | Empty deriving (Enum, Show)
type TreeDef = [TStruct]

printTStruct :: TStruct -> Char
printTStruct NonEmpty = '1'
printTStruct Empty = '0'

printTreeDef :: TreeDef -> String
printTreeDef = map printTStruct

enumBinTrees :: Int -> [TreeDef]
enumBinTrees n = enumBinTrees' n n where
  enumBinTrees' ups rights | rights < ups = mempty
  enumBinTrees' 0   rights = return (replicate (rights+1) Empty)
  enumBinTrees' ups rights = do
    step <- enumFrom (toEnum 0)
    let suffixes =
          case step of
            NonEmpty -> enumBinTrees' (ups - 1) rights
            Empty -> enumBinTrees' ups (rights - 1)
    suffix <- suffixes
    return (step:suffix)

mainExample = do
  print $ map printTreeDef $ enumBinTrees 4

โปรดทราบว่าฉันไม่ได้ตั้งใจที่จะยอมรับสิ่งนี้เป็นคำตอบแค่คิดว่าฉันจะโยนของฉันที่นั่น
Kyle Butt

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