นินจาและลิงและหมีโอ้ฉัน!


37

ความท้าทายนี้เป็นรางวัลจากNinjaBearMonkeyในการชนะBlock Building Bot Flocksของฉัน! ท้าทายด้วยการส่งอัศวินดำ ขอแสดงความยินดี NinjaBearMonkey!

ความท้าทายที่นี่ค่อนข้างง่าย แต่มีวิธีการที่เป็นไปได้หลากหลาย เรื่องราวดังกล่าวเกิดขึ้นในโลกแห่งภาพสามมิติที่มีสิ่งมีชีวิต 6 แบบ:

  1. นินจาตัวย่อ N
  2. หมีตัวย่อ B
  3. ลิงตัวย่อ M
  4. NinjaBears โดยย่อ NB
  5. BearMonkeys ตัวย่อ BM
  6. NinjaBearMonkeys ย่อ NBM

( NinjaBearMonkeyเป็นประเภทสุดท้ายที่ทรงพลังที่สุด)

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

  • ตัวอย่างใด ๆNBMคือ 1 NinjaBearMonkey และสิ่งมีชีวิตอื่น ๆ 0 รายการ
  • ตัวอย่างที่NBไม่ได้ตามมาMคือ 1 NinjaBear และสิ่งมีชีวิตอื่น ๆ 0 รายการ
  • อินสแตนซ์ใด ๆ ที่BMไม่ได้นำหน้าด้วยNคือ 1 BearMonkey และสิ่งมีชีวิตอื่น ๆ 0 รายการ
  • มิฉะนั้นอินสแตนซ์ของN, BและMเป็นนินจาเดียว, หมีและลิงตามลำดับ

บรรทัดถูกอ่านจากซ้ายไปขวา

ตัวอย่างเช่นในสายของสิ่งมีชีวิตNBMMBNBNBMมี 0 Ninjas, 1 Bear, 1 Monkey, 1 NinjaBear, 0 BearMonkeys และ 2 NinjaBearMonkeys

ท้าทาย

เขียนโปรแกรมหรือฟังก์ชั่นที่ใช้ในสายของตัวละครN, BและM, และพิมพ์หรือผลตอบแทนหลายวิธีของแต่ละ 6 ประเภทของสิ่งมีชีวิตที่มีอยู่ในนั้น

ผลลัพธ์ควรมีแบบฟอร์ม

#N #B #M #NB #BM #NBM

ด้วยจำนวนสิ่งมีชีวิตที่เกี่ยวข้องแทนที่แต่ละ#สัญญาณ ต้องแสดงจำนวนทั้งหมด 6 รายการคั่นด้วยช่องว่างแม้ว่าจะเป็น 0 อย่างไรก็ตามอาจอยู่ในลำดับใดก็ได้ (เช่น#NBMมาก่อน)

นอกจากนี้:

  • สายป้อนเพียงจะมีตัวละครN, และBM
  • หากสตริงที่ว่างเปล่าเป็นอินพุตแล้วจำนวนทั้งหมดเป็น 0
  • เอาท์พุทอาจมีทางเลือกชั้นนำและ / หรือพื้นที่ต่อท้ายและ / หรือขึ้นบรรทัดใหม่ต่อท้ายเดียว

การส่งที่สั้นที่สุดในหน่วยไบต์ชนะ

ตัวอย่าง

อินพุต: NB
เอาต์พุต:0N 0B 0M 1NB 0BM 0NBM

อินพุต: NBM
เอาต์พุต:0N 0B 0M 0NB 0BM 1NBM

อินพุต: NBMMBNBNBM(ตัวอย่างจากด้านบน)
เอาต์พุต:0N 1B 1M 1NB 0BM 2NBM

อินพุต: MBNNBBMNBM
เอาต์พุต:1N 1B 1M 1NB 1BM 1NBM

อินพุต: NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM
เอาต์พุต:17N 6B 14M 5NB 8BM 3NBM


53
ฉันอนุมัติการท้าทายนี้
NinjaBearMonkey

เพียงเพื่อยืนยัน: หากสิ่งที่คุณมีคือ NinjaBearMonkeys 2 รายการคุณจะไม่สามารถสร้างบรรทัดได้หรือไม่ เพราะพวกเขาไม่สามารถยืนเคียงข้างกัน?
อลันแคมป์เบล

3
@AlanCampbell No. NBMNBMจะเป็นการป้อนข้อมูลที่ถูกต้องสมบูรณ์แบบ อ่านจากซ้ายไปขวามี 2 NinjaBearMonkeys อย่างชัดเจน
งานอดิเรกของ Calvin

คำตอบ:


20

Pyth, 22 ไบต์

 f|pd+/zTT=:zTd_.:"NBM

ค่อนข้างแฮ็ควิธีการบันทึก 1 ไบต์ขอบคุณ @Jakube


Pyth, 23 ไบต์

FN_.:"NBM")pd+/zNN=:zNd

สาธิต.

พิมพ์ในลำดับย้อนกลับที่มีพื้นที่ต่อท้ายและไม่มีการขึ้นบรรทัดใหม่

.:"NBM")คือสตริงย่อยทั้งหมด_วางไว้ในลำดับที่ถูกต้อง/zNนับจำนวนที่ปรากฏและ=:zNdแทนที่แบบแทนที่แต่ละครั้งของสตริงที่เป็นปัญหาด้วยช่องว่าง

FN_.:"NBM")pd+/zNN=:zNd
FN                         for N in                            :
  _                                 reversed(                 )
   .:     )                                  substrings(     )
     "NBM"                                              "NBM"
           pd              print, with a space at the end,
              /zN          z.count(N)
             +   N                    + N
                  =:zNd    replace N by ' ' in z.

23

JavaScript ES6, 86 ไบต์

f=s=>'NBM BM NB M B N'.replace(/\S+/g,e=>(i=0,s=s.replace(RegExp(e,'g'),_=>++i))&&i+e)

(ฉันต้องตอบคำถามนี้) มันผ่านแต่ละซับสตริงของNBMเริ่มต้นด้วยสตริงที่ยาวกว่าซึ่งมีลำดับความสำคัญสูงกว่า มันค้นหาแต่ละครั้งของสตริงนั้นและลบออก (ในกรณีนี้แทนที่ด้วยจำนวนปัจจุบันดังนั้นมันจะไม่ถูกจับคู่อีกครั้ง) ในที่สุดมันก็จะแทนที่แต่ละสตริงย่อยด้วย count + the string

Stack Snippet นี้เขียนในเทียบเท่า ES5 ของโค้ดด้านบนเพื่อให้ง่ายต่อการทดสอบจากเบราว์เซอร์ใด ๆ มันเป็นรหัส ungolfed เล็กน้อย UI จะอัปเดตทุกการกดแป้น

f=function(s){
  return'NBM BM NB M B N'.replace(/\S+/g,function(e){
    i=0
    s=s.replace(RegExp(e,'g'),function(){
      return++i
    })
    return i+e
  })
}

run=function(){document.getElementById('output').innerHTML=f(document.getElementById('input').value)};document.getElementById('input').onkeyup=run;run()
<input type="text" id="input" value="NBMMBNBNBM" /><br /><samp id="output"></samp>


คุณสามารถเปลี่ยนส่วน regex เป็น'NBM<newline>BM<newline>...<newline>N'.replace(/./g, ...)'ที่ซึ่ง<newline>s เป็นตัวอักษรขึ้นบรรทัดใหม่และ's คือ backticks สร้างสตริงแม่แบบ ES6 หรือไม่ บันทึกสองไบต์ใน regex ( .ไม่ตรงกับบรรทัดใหม่)
wchargin

@WChargin แต่น่าเสียดายที่ไม่เพราะผลลัพธ์จะต้องคั่นด้วยช่องว่าง
NinjaBearMonkey

17

Python 2, 78

n=input()
for x in"NBM BM NB M B N".split():n=`n`.split(x);print`len(n)-1`+x,

ตัวแปรของคำตอบของVioz- . สนุกกับการเป็นตัวแทนสตริง Python 2!

นับจำนวนสตริงย่อยทางอ้อมโดยแยกออกนับชิ้นส่วนและลบ 1 แทนที่จะแทนที่สตริงย่อยด้วยสัญลักษณ์ฟิลเลอร์แทนที่สตริงด้วยรายการที่splitสร้างขึ้น จากนั้นเมื่อเราใช้การแทนสตริงส่วนต่างๆจะถูกคั่นด้วยช่องว่างและเครื่องหมายจุลภาค


5
นั่นมันบ้า! เป็นบ้า แต่ยังบ้า
Sp3000

เยี่ยมมาก! ไม่คิดอย่างนั้น :)
Kade

14

Ruby, 166 80 72 68 ตัวอักษร

f=->s{%w(NBM BM NB M B N).map{|t|c=0;s.gsub!(t){c+=1};c.to_s+t}*' '}

คำอธิบาย:

  • การนับจะทำในสิ่งที่ตรงกันข้าม นี่เป็นเพราะนินจาและหมีและลิงที่ยาวกว่ามีความสำคัญมากกว่าตัวที่สั้นกว่า

  • สำหรับNBM, BMและNB, ลำดับจะgsub!'ออกมาจากสายเดิมด้วยบล็อกเพื่อนับจำนวนลำดับเหล่านี้อยู่ (ใช่ฟังก์ชั่นแก้ไขข้อโต้แย้งของมัน)

    • อย่างไรก็ตามพวกเขาไม่สามารถถูกแทนที่ด้วยอะไรตั้งแต่มิฉะนั้นBNBMMจะถูกนับเป็นNBMและBMแทนB, NBMและM(เพราะเมื่อNBMจะถูกลบออกก็จะใส่BและMร่วมกันและจะไม่มีทางที่จะแยกแยะความแตกต่างมัน) เดิมทีฉันส่งคืนสตริงอักขระเดียว ( .gsub!('NBM'){c+=1;?|}) แต่ฉันรู้ว่าฉันสามารถส่งคืนผลลัพธ์ของ+=(ซึ่งเป็นตัวเลขได้ดังนั้นจึงไม่สามารถเป็นได้N B M)
  • สำหรับM, BและN, ฉันสามารถทำได้แค่countกี่คนในสตริง (ไม่จำเป็นต้องลบออกผ่านgsub!) ตอนนี้มันเป็นลูป (ไม่รู้ว่าทำไมฉันไม่คิดในตอนแรก) ดังนั้นสิ่งเหล่านี้ก็ทำแบบเดียวกัน


วิธีการแก้ปัญหาที่คล้ายกันในนกกระจอกเทศ , 54 51 ตัวอักษร :

:s;`NBM BM NB M B N`" /{:t0:n;s\{;n):n}X:s;nt+}%" *

น่าเสียดายที่ไม่ใช่โซลูชันที่ถูกต้องเนื่องจากมีข้อบกพร่องในรุ่นนกกระจอกเทศปัจจุบัน (ซึ่งตอนนี้ได้รับการแก้ไขแล้ว แต่หลังจากการโพสต์ความท้าทายนี้)


คุณสามารถบันทึกได้ 3 ตัวอักษรโดยใช้สัญกรณ์อาร์เรย์%w(NBM BM NB M B N)และนำตัวแยกออก
DickieBoy

@DickieBoy นั่นคือ 4 ตัวอักษรจริง ๆ ; ขอบคุณ!
Doorknob

อ่าใช่แล้ว!
DickieBoy

14

Java, 166 162

void f(String a){String[]q="NBM-NB-BM-N-B-M".split("-");for(int i=0,c;i<6;System.out.print(c+q[i++]+" "))for(c=0;a.contains(q[i]);c++)a=a.replaceFirst(q[i],".");}

และมีตัวแบ่งบรรทัดไม่กี่:

void f(String a){
    String[]q="NBM-NB-BM-N-B-M".split("-");
    for(int i=0,c;i<6;System.out.print(c+q[i++]+" "))
        for(c=0;a.contains(q[i]);c++)
            a=a.replaceFirst(q[i],".");
}

มันใช้งานได้ง่ายมาก เพียงวนรอบโทเค็นแทนที่ด้วยจุดและนับตราบใดที่อินพุตมีบางอย่าง นับของใหญ่ก่อนดังนั้นของเล็ก ๆ น้อย ๆ จะไม่เลอะ

ตอนแรกฉันพยายามแทนที่ทั้งหมดในครั้งเดียวและนับความแตกต่างของความยาว แต่ใช้ตัวละครเพิ่มอีกสองสามวิธี :(


2
ในฐานะที่เป็น Java dev ฉันต้องการทำให้สั้นลงและเห็นการชนะของ Java สำหรับการเปลี่ยนแปลง หลังจากจ้องมองมันสักครู่ฉันยังไม่ได้หาวิธีทำให้มันสั้นลง
DeadChex

1
แน่นอนว่ามันจะไม่ชนะโดยรวม ผู้นำในปัจจุบันคือ 22 ไบต์และไม่มีทางที่จะทำอะไรที่มีความหมายใน Java ในขนาดนั้น printlnคำสั่งของฉันคนเดียวมีขนาดใหญ่กว่านั้น แม้ว่าฉันจะพอใจกับมัน: D
Geobits

1
ฉันสายไปหน่อย แต่ฉันพบวิธี ... เปลี่ยนString q[]=เป็นString[]q=
DeadChex

1
ดี! ไม่อยากจะเชื่อเลยว่าฉันพลาดไปแล้วมันอยู่ในรายการมาตรฐานของสิ่งต่าง ๆ ให้ดู :)
Geobits

ฉันเพิ่งค้นพบมันหลังจากพยายามเข้า Code Golf ในฐานะ JavaDev ฉันค่อนข้างประหลาดใจกับสิ่งที่คุณสามารถทำได้
DeadChex

11

CJam, 36 32 31 ไบต์

l[ZYX]"NBM"few:+{A/_,(A+S@`}fA;

ขอบคุณ @Optimizer สำหรับการเล่นกอล์ฟ 1 ไบต์

ลองใช้ออนไลน์ในล่าม CJam

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

l                                e# Read a line L from STDIN.
 [ZYX]"NBM"                      e# Push [3 2 1] and "NBM".
           few                   e# Chop "NBM" into slices of length 3 to 1.
              :+                 e# Concatenate the resulting arrays of slices.
                {          }fA   e# For each slice A:
                 A/              e#   Split L at occurrences of A.
                   _,(           e#   Push the numbers of resulting chunks minus 1.
                      A+         e#   Append A.
                        S        e#   Push a space.
                         @`      e#   Push a string representation of the split L.
                              ;  e# Discard L.


@ เพิ่มประสิทธิภาพ: ใช้งานได้ดี ขอบคุณ
Dennis

7

R, 153 134 118

มันใช้เวลานานขึ้นอย่างรวดเร็ว แต่หวังว่าฉันจะสามารถโกนหนวดได้เล็กน้อย อินพุตคือ STDIN และเอาต์พุตไปยัง STDOUT

แก้ไขการเปลี่ยนแทค กำจัดสตริงการแยกและชิ้นส่วนการนับ ตอนนี้ฉันเปลี่ยนชิ้นส่วนด้วยสตริงที่สั้นกว่าชิ้นส่วน ความแตกต่างระหว่างความยาวสตริงถูกรวบรวมสำหรับเอาท์พุท

N=nchar;i=scan(,'');for(s in scan(,'',t='NBM BM NB M B N'))cat(paste0(N(i)-N(i<-gsub(s,strtrim('  ',N(s)-1),i)),s),'')

คำอธิบาย

N=nchar;
i=scan(,'');                     # Get input from STDIN
for(s in scan(,'',t='NBM BM NB M B N'))  # Loop through patterns
  cat(                           # output
    paste0(                      # Paste together
      N(i) -                     # length of i minus
      N(i<-gsub(                 # length of i with substitution of
        s,                       # s
        strtrim('  ',N(s)-1)     # with a space string 1 shorter than s
        ,i)                      # in i
      ),
      s)                         # split string
  ,'')

ทดสอบการทำงาน

> N=nchar;i=scan(,'');for(s in scan(,'',t='NBM BM NB M B N'))cat(paste0(N(i)-N(i<-gsub(s,strtrim('  ',N(s)-1),i)),s),'')
1: NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM
2: 
Read 1 item
Read 6 items
3NBM 8BM 5NB 14M 6B 17N 
> N=nchar;i=scan(,'');for(s in scan(,'',t='NBM BM NB M B N'))cat(paste0(N(i)-N(i<-gsub(s,strtrim('  ',N(s)-1),i)),s),'')
1: NBMMBNBNBM
2: 
Read 1 item
Read 6 items
2NBM 0BM 1NB 1M 1B 0N 
> 

7

Pyth, 19 ไบต์

jd+Ltl=zc`zd_.:"NBM

นี่คือส่วนผสมของโซลูชัน Pyth ของ @ isaacg และเคล็ดลับ Python ของ @ xnor

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

คำอธิบาย

jd+Ltl=zc`zd_.:"NBM   implicit: z = input string
             .:"NBM   generate all substrings of "NBM"
            _         invert the order
  +L                  add left to each d in ^ the following:
         `z             convert z to a string
        c  d            split at d
      =z                assign the resulting list to z
    tl                  length - 1
jd                    join by spaces and implicit print

6

Julia, 106 97 ไบต์

b->for s=split("NBM BM NB M B N") print(length(matchall(Regex(s),b)),s," ");b=replace(b,s,".")end

สิ่งนี้จะสร้างฟังก์ชั่นที่ไม่มีชื่อที่ใช้สตริงเป็นอินพุตและพิมพ์ผลลัพธ์ไปที่ STDOUT ด้วยการเว้นวรรคหนึ่งช่องและไม่ขึ้นบรรทัดใหม่ f=b->...เรียกว่าให้มันชื่อเช่น

คำอธิบาย Ungolfed +:

function f(b)
    # Loop over the creatures, biggest first
    for s = split("NBM BM NB M B N")

        # Get the number of creatures as the count of regex matches
        n = length(matchall(Regex(s), b))

        # Print the number, creature, and a space
        print(n, s, " ")

        # Remove the creature from captivity, replacing with .
        b = replace(b, s, ".")
    end
end

ตัวอย่าง:

julia> f("NBMMBNBNBM")
2NBM 0BM 1NB 1M 1B 0N 

julia> f("NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM")
3NBM 8BM 5NB 14M 6B 17N 

4

Python 2, 93 88 89 84 ไบต์

ใช้วิธีการที่ตรงไปตรงมา

def f(n):
 for x in"NBM BM NB M B N".split():print`n.count(x)`+x,;n=n.replace(x,"+")

โทรเช่น:

f("NBMMBNBNBM")

เอาท์พุทเป็นเช่นนั้น:

2NBM 0BM 1NB 1M 1B 0N

inคุณสามารถลบพื้นที่หลัง
isaacg

ใน Python 2 คุณสามารถแปลงเป็นการแสดงสตริงด้วย `x '
xnor

4

SAS, 144 142 139 129

data;i="&sysparm";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;

การใช้งาน (เพิ่ม 7 ไบต์สำหรับ sysparm):

$ sas -stdio -sysparm NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM << _S
data;i="&sysparm";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;
_S

หรือ

%macro f(i);i="&i";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1‌​,i);put a+(-1)z@;end;%mend;

การใช้งาน:

data;%f(NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM)

ผลลัพธ์:

3NBM 5NB 8BM 17N 6B 14M

คุณสามารถบันทึกคู่ไบต์ใช้ในสถานที่ของcats('s/',z,'/x/') 's/'||strip(z)||'/x/'
Alex A.

1
Nice นั่นเป็นการเดินทางย้อนกลับไปถึง 139 :)
Egg Egg ทอด

1
126 bytes:macro a i="&sysparm";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;%
Alex A.

1
data;i="&sysparm";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;122: เมื่อคุณอ่านแล้วsysparmคุณอาจเรียกใช้เป็นขั้นตอนข้อมูล run;และถ้าคุณกำลังทำงานในชุดคุณไม่จำเป็นต้อง
อเล็กซ์ A.

1
แต่คุณจะได้ 129 จากการใช้มาโครสไตล์โมเดิร์นซึ่งไม่ได้อ่านจากอาร์กิวเมนต์บรรทัดคำสั่ง:%macro a(i);i="&i";do z='NBM','NB','BM','N','B','M';a=count(i,z,'t');i=prxchange(cats('s/',z,'/x/'),-1,i);put a+(-1)z@;end;%mend;
อเล็กซ์ A.

3

PHP4.1, 92 ไบต์

ไม่ใช่อันที่สั้นที่สุด แต่มีอะไรอีกที่คุณคาดหวังจาก PHP

หากต้องการใช้งานให้ตั้งรหัสบน COOKIE, POST, GET, SESSION ...

<?foreach(split(o,NBMoNBoBMoMoBoN)as$a){echo count($T=split($a,$S))-1,"$a ";$S=join('',$T);}

apporach เป็นพื้นฐาน:

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

ง่ายใช่มั้ย


2

JavaScript, 108 116 ไบต์

เพียงวิธีการตรงไปข้างหน้าไม่มีอะไรแฟนซี

o="";r=/NBM|NB|BM|[NMB]/g;g={};for(k in d=(r+prompt()).match(r))g[d[k]]=~-g[d[k]];for(k in g)o+=~g[k]+k+" ";alert(o);

1
ไม่ได้ผล: All 6 counts must be shown, separated by spaces, even when they are 0.. กรณีทดสอบ:N
edc65

@ edc65 Woah ฉันเพิ่งพลาดส่วนนั้นไป ขอบคุณสำหรับการชี้ให้เห็นว่า แก้ไขค่าใช้จ่าย 8chars
C5H8NNaO4


1

SpecBAS - 164

1 INPUT s$
2 FOR EACH a$ IN ["NBM","BM","NB","M","B","N"]
3 LET n=0
4 IF POS(a$,s$)>0 THEN INC n: LET s$=REPLACE$(s$,a$,"-"): GO TO 4: END IF
5 PRINT n;a$;" ";
6 NEXT a$

ใช้วิธีการเดียวกันกับคนอื่น ๆ มากมาย บรรทัดที่ 4 จะวนลูปไว้เหนือสตริง (จากค่าที่ใหญ่ที่สุดก่อน) แทนที่หากพบ

SpecBAS มีสัมผัสที่ดีกว่า ZX / Sinclair BASIC ดั้งเดิม (วนซ้ำไปตามลิสต์, ค้นหาตัวละคร) ซึ่งฉันยังคงหาคำตอบอยู่


1

C, 205 186 184 ไบต์

วิธีการที่แตกต่างกันเล็กน้อยขึ้นอยู่กับสถานะของเครื่อง ที่tเป็นของรัฐ

a[7],t,i;c(char*s){do{i=0;t=*s==78?i=t,1:*s-66?*s-77?t:t-4?t-2?i=t,3:5:6:t-1?i=t,2:4;i=*s?i:t;a[i]++;}while(*s++);printf("%dN %dB %dM %dNB %dBM %dNBM",a[1],a[2],a[3],a[4],a[5],a[6]);}

ขยาย

int a[7],t,i;

void c(char *s)
{
    do {
        i = 0;
        if (*s == 'N') {
            i=t; t=1;
        }
        if (*s == 'B') {
            if (t==1) {
                t=4;
            } else {
                i=t;
                t=2;
            }
        }
        if (*s == 'M') {
            if (t==4) {
                t=6;
            } else if (t==2) {
                t=5;
            } else {
                i=t;
                t=3;
            }
        }
        if (!*s)
            i = t;
        a[i]++;
    } while (*s++);
    printf("%dN %dB %dM %dNB %dBM %dNBM",a[1],a[2],a[3],a[4],a[5],a[6]);
}

ฟังก์ชั่นทดสอบ

#include <stdio.h>
#include <stdlib.h>

/*
 * 0 : nothing
 * 1 : N
 * 2 : B
 * 3 : M
 * 4 : NB
 * 5 : BM
 * 6 : NBM
 */
#include "nbm-func.c"

int main(int argc, char **argv)
{
    c(argv[1]);
}

จะไม่ใช้for(;;*s++){...}แทนที่จะdo{...}while(*s++);บันทึกบางไบต์ใช่ไหม printfนอกจากนี้คุณไม่จำเป็นต้องมีตัวอักษรขึ้นบรรทัดใหม่ใน
Spikatrix

for(;*s;s++)ฉันคิดว่าคุณหมายถึง แต่ฉันต้องวนซ้ำกับตัวละครโมฆะตัวสุดท้าย โทรดีในการบันทึก\nซึ่งไม่จำเป็นต้องใช้
ผู้ใช้บางคน

1

C, 146

f(char*s)
{
  char*p,*q="NBM\0NB\0BM\0N\0B\0M",i=0,a=2;
  for(;i<6;q+=a+2,a=i++<2)
  {
    int n=0;
    for(;p=strstr(s,q);++n)*p=p[a>1]=p[a]=1;
    printf("%d%s ",n,q);
  }
}

// Main function, just for testing
main(c,a)char**a;{
  f(a[1]);
}  

1

Haskell - 177 ไบต์ (ไม่มีการนำเข้า)

n s=c$map(\x->(show$length$filter(==x)(words$c$zipWith(:)s([f(a:[b])|(a,b)<-zip s(tail s)]++[" "])))++x++" ")l
f"NB"=""
f"BM"=""
f p=" "
l=["N","B","M","NB","BM","NBM"]
c=concat

(ขออภัยสำหรับความรู้ทางอินเทอร์เน็ตที่นี่)

แพลตฟอร์ม Haskell ไม่มีการค้นหาสตริงโดยไม่มีการนำเข้าและฉันต้องการแสดงและใช้ประโยชน์จากความจริงที่ว่าสตริงการค้นหานั้นเป็นสตริงย่อยทั้งหมดของหนึ่ง (โดยไม่มีการทำซ้ำ) ดังนั้นการจัดกลุ่มอักขระสามารถทำได้โดยการระบุคู่ที่ได้รับอนุญาต ติดตามซึ่งกันและกันนั่นคือสิ่งที่fทำที่นี่

ฉันยังต้องการรายการทั้งหมดlในตอนท้ายเพื่อตรวจสอบความเท่าเทียมกันและแสดงให้ตรงตามที่ต้องการ แต่จะไม่ได้รับความท้าทายเพียงเพื่อรายงานจำนวนการเกิดขึ้นที่เป็นไปได้wordsในลำดับใด ๆ


0

Bash - 101

I=$1
for p in NBM BM NB M B N;{ c=;while [[ $I =~ $p ]];do I=${I/$p/ };c+=1;done;echo -n ${#c}$p\ ;}

ส่งผ่านสตริงเป็นอาร์กิวเมนต์แรก

bash nmb.sh MBNNBBMNBM 

อธิบายเล็กน้อย:

# We have to save the input into a variable since we modify it.
I=$1

# For each pattern (p) in order of precedence
for p in NBM BM NB M B N;do
    # Reset c to an empty string
    c=

    # Regexp search for pattern in string
    while [[ $I =~ $p ]];do
        # Replace first occurance of pattern with a space
        I=${I/$p/ }
        # Append to string c. the 1 is not special it could be any other
        # single character
        c+=1
    done

    # -n Suppress's newlines while echoing
    # ${#c} is the length on the string c
    # Use a backslash escape to put a space in the string.
    # Not using quotes in the golfed version saves a byte.
    echo -n "${#c}$p\ "
done

0

อาร์เอส , 275 ไบต์

(NBM)|(NB)|(BM)|(N)|(B)|(M)/a\1bc\2de\3fg\4hi\5jk\6l
[A-Z]+/_
#
+(#.*?)a_b/A\1
+(#.*?)c_d/B\1
+(#.*?)e_f/C\1
+(#.*?)g_h/D\1
+(#.*?)i_j/E\1
+(#.*?)k_l/F\1
#.*/
#
#(A*)/(^^\1)NBM #
#(B*)/(^^\1)NB #
#(C*)/(^^\1)BM #
#(D*)/(^^\1)N #
#(E*)/(^^\1)B #
#(F*)/(^^\1)M #
\(\^\^\)/0
 #/

การสาธิตสดและการทดสอบ

ผลงานง่าย แต่แปลกเล็กน้อย:

(NBM)|(NB)|(BM)|(N)|(B)|(M)/a\1bc\2de\3fg\4hi\5jk\6l

การสร้างสรรค์นี้ใช้กลุ่มเพื่อเปลี่ยนอินพุตเช่น:

NBMBM

เข้าไป

aNBMbcdeBMfghijkl

บรรทัดถัดไป:

[A-Z]+/_

สิ่งนี้จะแทนที่ลำดับของตัวพิมพ์ใหญ่ด้วยการขีดล่าง

#

สิ่งนี้จะแทรกเครื่องหมายปอนด์ที่จุดเริ่มต้นของบรรทัด

+(#.*?)a_b/A\1
+(#.*?)c_d/B\1
+(#.*?)e_f/C\1
+(#.*?)g_h/D\1
+(#.*?)i_j/E\1
+(#.*?)k_l/F\1
#.*/

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

#

ปอนด์จะถูกแทรกอีกครั้งที่จุดเริ่มต้นของบรรทัด

#(A*)/(^^\1)NBM #
#(B*)/(^^\1)NB #
#(C*)/(^^\1)BM #
#(D*)/(^^\1)N #
#(E*)/(^^\1)B #
#(F*)/(^^\1)M #
\(\^\^\)/0
 #/

อักษรตัวใหญ่จะถูกแทนที่ด้วยข้อความเทียบเท่ากับการนับที่เกี่ยวข้อง เนื่องจากข้อผิดพลาดใน rs (ฉันไม่ต้องการเสี่ยงที่จะแก้ไขและถูกตัดสิทธิ์) ลำดับที่ว่างเปล่าจะถูกเปลี่ยนเป็น(^^)ซึ่งถูกแทนที่ด้วย 0 ในบรรทัดที่สองถึงครั้งสุดท้าย บรรทัดสุดท้ายนั้นจะลบปอนด์ออก


0

KDB (Q), 76 ไบต์

{" "sv string[-1+count@'enlist[x]{y vs" "sv x}\l],'l:" "vs"NBM NB BM N B M"}

คำอธิบาย

                                                   l:" "vs"NBM NB BM N B M"     / substrings
                        enlist[x]{y vs" "sv x}\l                                / replace previous substring with space and cut
              -1+count@'                                                        / counter occurrence
       string[                                  ],'                             / string the count and join to substrings
{" "sv                                                                     }    / concatenate with space, put in lambda

ทดสอบ

q){" "sv string[-1+count@'enlist[x]{y vs" "sv x}\l],'l:" "vs"NBM NB BM N B M"}"NNNMNBMMBMMBMMMNBMNNMNNNBNNNBNBBNBNMMNBBNBMMBBMBMBBBNNMBMBMMNNNNNMMBMMBM"
"3NBM 5NB 8BM 17N 6B 14M"
q){" "sv string[-1+count@'enlist[x]{y vs" "sv x}\l],'l:" "vs"NBM NB BM N B M"}""
"0NBM 0NB 0BM 0N 0B 0M"

0

Haskell: 244 ไบต์

import Data.List
s="NBM"
[]#_=[[]]
a#[]=[]:a#s
l@(a:r)#(b:m)
 |a==b=let(x:y)=r#m in((a:x):y)
 |True=[]:l#m
c?t=length$filter(==t)c
p=["N","B","M","NB","BM","NBM"]
main=getLine>>= \l->putStrLn.intercalate " "$map(\t->show((l#[])?t)++t)p

บางคำแนะนำ: คุณกำลังใช้pและsเพียงครั้งเดียวดังนั้นไม่มีความจำเป็นที่จะให้มันชื่อ (-> a#[]=[]:a#"NBM", เดียวกันp) BTW: words"N B M NB BM NBM"แทนที่จะเป็นรายการของสตริงจะบันทึกไบต์เพิ่มเติม importเป็นเพียงสำหรับintercalateมันเต้สั้นอีกครั้งใช้มันและกำจัดของ...putStrLn.tail.((' ':)=<<)$map... importใส่ยามทั้งหมด|ในความหมายของ#ในบรรทัดเดียวและใช้1<2แทนTrue: ...#(b:m)|a==b=...l#m|1<2=[]......
nimi

... ?สามารถกำหนดให้สั้นลงด้วยรายการความเข้าใจ: c?t=sum[1|x<-c,x==t]. อีกครั้งที่คุณใช้เพียงครั้งเดียวเพื่อใช้ร่างกายโดยตรง? ...show(sum[1|x<-l#[],x==t])
nimi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.