একটি ছোট ভাষা একটি ছোট দোভাষী দাবী করে


21

এখানে একটি খুব সাধারণ ভাষার সংজ্ঞা দেওয়া হয়েছে:

A Variable is any string that does not contain ^, <, >, !, or ?
The empty string is a valid variable identifier
The value of every variable starts at 0.
A Statement is one of (var is a Variable, P is a Program):
    var^   -> changes var to be equal to 1 more than itself
    var<P> -> while var > 0, changes var to be equal to 1 less than itself, then runs P
    var! -> output value of var
    var? -> ask for non-negative integer as input, increase var by that value
A Program is a concatenation of Statements, running a Program means running each Statement in order

প্রোগ্রামগুলির উদাহরণ (নোট করুন যে খালি স্ট্রিংটি একটি পরিবর্তনশীল, তবে আমি স্বচ্ছতার জন্য এটিকে অল্প পরিমাণে ব্যবহার করব এবং কিছু ভেরিয়েবল প্রোগ্রামে সাধারণত শূন্য হয় যখন তারা সাধারণত ডিফল্ট হিসাবে 0 হয়):

<>: sets the value of the empty string variable to 0
b<>b?b<a^>: asks for b, then adds the value stored in b to a, zeroing b in the process
b<>b?a<>b<a^>: asks for b, then sets a to the value of b, zeroing b in the process
a<>c<>b<a^c^>c<b^> : copies the value in b into a without zeroing it
b<>c<>a<c^c^c<b^>>b! : outputs a multiplied by 2
b^b<a<>a?a!b^> : outputs what you input, forever

আপনার লক্ষ্য এই ভাষার জন্য ক্ষুদ্রতম দোভাষী লিখুন।

  1. একটি ভেরিয়েবলের মানটি নির্বিচারে বড় হতে পারে এবং কেবলমাত্র তাত্ত্বিকভাবে আপনার ভাষাতে অ্যাক্সেস পাওয়া মোট স্মৃতি দ্বারা সীমাবদ্ধ হওয়া উচিত তবে আপনাকে কেবল 2 ^ 256 পর্যন্ত মানগুলি পরিচালনা করতে হবে।

  2. আপনার প্রোগ্রামটি তাত্ত্বিকভাবে নির্বিচারে দীর্ঘ প্রোগ্রামগুলি পরিচালনা করতে সক্ষম হওয়া উচিত তবে আপনাকে কেবল 2 ^ 32 অক্ষরের দীর্ঘ প্রোগ্রামগুলির মধ্যে কাজ করতে হবে। আপনার পাশাপাশি 2 ^ 32 অবধি গভীরতার নেস্টেড লুপগুলি পরিচালনা করতে হবে।

  3. আপনি ধরে নিতে পারেন যে প্রোগ্রামটি একটি বৈধ প্রোগ্রাম এবং আপনি যখনই ইনপুট চেয়েছেন তখনই আপনি কেবল অ-নেতিবাচক পূর্ণসংখ্যা পাবেন। আপনি ধরে নিতে পারেন যে কেবলমাত্র ASCII মুদ্রণযোগ্য অক্ষরগুলি ইনপুট স্ট্রিংয়ের অন্তর্ভুক্ত।

  4. আপনি যে প্রোগ্রামটির ব্যাখ্যা করেছেন তার গতি তাতে কিছু যায় আসে না, এটি ইতিমধ্যে--সংখ্যার গুণকের মতো অপরিশোধন ছাড়াই যন্ত্রণাদায়কভাবে ধীর হয়ে যাবে।

  5. আপনি যদি এমন কোনও ভাষা ব্যবহার করতে চান যা ভাষা দ্বারা বর্ণিত পদ্ধতিতে যুক্তিসঙ্গতভাবে ইনপুট গ্রহণ করতে বা আউটপুট তৈরি করতে না পারে, আপনি এটি সম্ভব করতে যে কোনও ব্যাখ্যা ব্যবহার করুন। এটি আপনার ভাষা কিছু প্রয়োজনীয় আচরণ বাস্তবায়িত করতে পারে না এমন কোনও কারণে প্রযোজ্য। আমি চাই সমস্ত ভাষা প্রতিযোগিতায় সক্ষম হোক to

  6. সংক্ষিপ্ততম প্রোগ্রামের জয়। স্ট্যান্ডার্ড লুফোলস প্রযোজ্য।


সাইড চ্যালেঞ্জ হিসাবে আমি দেখতে চাই যে একটি প্রোগ্রাম আমি কতটা সংক্ষিপ্তভাবে লিখতে পারি যে এটি 2016 নম্বরটি ছাড়িয়েছে, তবে প্রথমে আমার একজন দোভাষীর লেখার জন্য অপেক্ষা করতে হবে যাতে আমি আমার কোডটি পরীক্ষা করতে পারি।
নিল

1
পাইথন ২.7 এ আমার একজন দোভাষী আছে
কাল্পনিক মেলুন

2
এই ভাষাকে কী বলা হয়? এটি esolangs.org
wizzwizz4

@Neil আমি 72 অক্ষর এটা করতে পরিচালিত
ঘর্ষিত তরমুজ

@ ফ্রিক্যটিভমেলন 72? আমি 43 এ এটি করতে পারি!
নীল

উত্তর:


4

রুবি, 182 বাইট

$h=Hash.new 0
def r(c)c.scan(/(([^!?^<>]*)(<(\g<1>*)>|[!?^]))/){$4?($1=~/(.*?)<(.*)>/
($h[$1]-=1;r$2)while$h[$1]>0):$3<?"?p($h[$2]):$h[$2]+=$3<?@?STDIN.gets.to_i:
1}end
r IO.read *$*

এটির মতো চেষ্টা করুন:

$ cat code
a?b<>c<>a<c^c^c<b^>>b!

$ ruby lynn.rb code
3                           <-- input
6                           <-- output

কিভাবে এটা কাজ করে

rফাংশন একটি ইনপুট স্ট্রিং tokenizes এবং প্রতিটি টোকেন executes:

def r(c)
    c.scan(/(([^!?^<>]*)(<(\g<1>*)>|[!?^]))/){
        ...
    }
end

আমরা কিছু পরিবর্তনশীল নামের সাথে $2মিলে যাচ্ছি [^!?^<>]*, তারপরেও হয়

  • <...>যেখানে ...শূন্য বা ততোধিক প্রোগ্রামের সাথে মিল রয়েছে ( \gপুনরাবৃত্তি), সেই ক্ষেত্রে $4তা নয় isn'tnil
  • !, ?বা ^চরিত্র, $3যার ক্ষেত্রে $4ধরা পড়ে nil

তারপরে টোকেনটি কার্যকর করার পক্ষে যুক্তিটি কিছুটা সহজভাবে যুক্ত করার সময় খুব সহজ:

$4 ? (                                    # If it's a loop:
    $1 =~ /(.*?)<(.*)>/                   #   Re-match token*
    ($h[$1]-=1; r $2) while $h[$1] > 0    #   Recurse to run loop
) :                                       # Else:
    $3 < ?"                               #   If it's an !:
      ? p($h[$2])                         #     Print the var
      : $h[$2] +=                         #   Else, increment it by:
          $3 < ?@                         #     If it's a ?:
              ? STDIN.gets.to_i           #       User input
              : 1                         #     Else: 1

* There's an oniguruma bug, I think, that keeps me from simply using $3 here.

এটি কীভাবে কাজ করে আমি সত্যিই আগ্রহী।
জেরি যেরেমিয়া

1

জাভাস্ক্রিপ্ট (ES6) 184 194 209

সরলীকৃত সম্পাদনা করুন (ইনপুট এবং আউটপুট জন্য ফাংশন প্যারামিটার ব্যবহার করে একটি দুর্দান্ত ধারণা বলে মনে হয়েছিল, তবে এটি ছিল না), আরও 1 বাইট সংরক্ষিত thx @ ӍѲꝆΛҐӍΛПҒЦꝆ

2 পরিবর্তিত পার্সিং সম্পাদনা করুন । ইনক্রিমেন্ট / ইনপুট জন্য যুক্তি @ লিন এর উত্তর থেকে ধার করা হয়

F=(p,i=0,v={},n='')=>eval("for(;c='>?^!<'.indexOf(q=p[i++]||'');n=~c?'':n+q)if(c>3){for(;v[n]--;)F(p,i,v);i=F(p,i,v[n]=0)}else~c&&v?c>2?alert(v[n]|0):v[n]=~~v[n]+(--c||+prompt()):0;i")

কম গল্ফড

F=(p,      // program 
   i = 0,  // initial instruction pointer  
   v = {}, // variables (default to empty) or if 0, flag of dummy execution
   n = ''    // name of current variable (has to be local for recursive calls)
{
  for(; c='>?^!<'.indexOf(q=p[i++]||''); )
  // q = current character
  // c = current command (int 0..4 or -1 id not recognized)
  //     note 0 end of subprogram or end of program
  {
    if(c>3) // 4='<' call subprogram - recursive
    {
      for(;v[n]--;)
        F(p,i,v); // conditional call, repeated - using real environment
      v[n] = 0; // Reset variable at loop end
      i=F(p,i,0) // one more unconditional dummy call, just to advance i
    }
    else
      ~c&&v? // if valid command (1..3) and not dummy
      c>2?
        alert(v[n]|0) // output, undefined becomes 0
        :v[n]=~~v[n]+(--c||+prompt()) // inc with 1 or user input
      :0     // not valid command or dummy, do nothing
    n=~c?'':n+q // reset or update current variable name
  }
  return i // return current istruction pointer (for recursive calls)
}

টেস্ট স্নিপেট @ নীল পোস্ট করা প্রোগ্রামটি ব্যবহার করে 2016 এর মূল্যায়ন শুরু করে। ধৈর্য্য ধারন করুন...

F=(p,i=0,v={},n='')=>eval("for(;c='>?^!<'.indexOf(q=p[i++]||'');n=~c?'':n+q)if(c>3){for(;v[n]--;)F(p,i,v);i=F(p,i,v[n]=0)}else~c&&v?c>2?alert(v[n]|0):v[n]=~~v[n]+(--c||+prompt()):0;i")

// TEST
function definput(){  I.disabled = KI.checked; }
function defoutput(){  O.disabled = KO.checked; }

function run()
{
  var prog=P.value, irows = I.value.split('\n'), pi=0;
  var fout=x=>O.value+=x+'\n';
  var fin=x=>irows[pi++];
  var saveAlert=alert, savePrompt=prompt
  if (!KO.checked) alert=fout,O.value=''
  if (!KI.checked) prompt=fin
  
  F(prog);
  
  alert=saveAlert
  prompt=savePrompt
}

P.value="^^^^<a^a^>a<^^^^><a^b^>a<c<b^^>b<c^^>>!"

run()
Program <button onclick="run()">RUN</button><br>
<textarea id=P></textarea><br>
Input (or <input type=checkbox id=KI onclick="definput()"> interactive prompt)<br>
<textarea id=I>5</textarea><br>
Output (or <input type=checkbox id=KO onclick="defoutput()"> popup)<br>
<textarea id=O readonly></textarea><br>


একটি বিকল্প না evalএড়ানোর জন্য ব্যবহার করা হয় return?
মামা ফান রোল

@। হ্যাঁ, ইভাল 1 বাইট সংরক্ষণ করে আমি এখনও আরও বেশি কিছু সন্ধান করছি
edc65

0

পার্ল, 251 বাইট

@p=split/([<>!?^])/,<>;for$c(0..$#p){$_=$p[$c];/</&&push@j,$c;if(/>/){$a=pop@j;$p[$c]=">$a";$p[$a]="<$c";}}while($c<$#p){$_=$p[$c];/\^/&&$v{$l}++;/!/&&print$v{$l};/\?/&&($v{$l}=<>);/<(\d+)/&&($v{$l}?$v{$l}--:($c=$1));/>(\d+)/&&($c=$1-2);$l=$_;$c++;} 

সংস্করণ পড়তে সহজ:

# treat the first line of input as a program

# split on punctuation keywords; @p will contain the program as a list
# of tokens (including whitespace between adjacent punctuation)
@p = split /([<>!?^])/, <>;

# rewrite jump addresses

# the interpreter could scan backwards to avoid this, but that idea
# makes me feel dirty
for $c (0..$#p) {
    $_ = $p[$c];
    # save loop-start address on stack
    /</ && push @j, $c;
    if (/>/) {
        # if we encounter a loop-end instruction, rewrite it and the
        # corresponding loop-start to include the address (of the
        # instruction---jumps have to offset from this)
        $a = pop @j;
        $p[$c] = ">$a";
        $p[$a] = "<$c";
    }
}

# execute the program

# our program is already in @p

# $c will contain our program counter

# $l will contain the name of the last-referenced variable

while ($c < $#p) {
    # move current instruction into $_ for shorter matching
    $_ = $p[$c];

    # increment instruction
    /\^/ && $v{$l}++;

    # output instruction
    /!/ && print $v{$l};

    # input instruction
    /\?/ && ($v{$l} = <>);

    # loop start, including address
    /<(\d+)/ && ($v{$l} ? $v{$l}-- : ($c = $1));

    # loop end, including address
    />(\d+)/ && ($c = $1-2);

    # copy current instruction into "last variable name"---this will
    # sometimes contain operators, but we have null-string
    # instructions between adjacent operators, so it'll be fine
    $l = $_;

    # advance the program counter
    $c++;
}

এটি সরাসরি জাম্প হওয়ার জন্য লুপগুলি ফিক্সিংয়ের একগুচ্ছ বর্জ্য অপচয় করে তবে লুপটির জন্য পিছনের দিকে স্ক্যান করা আমার নান্দনিকতার বোধকে ক্ষুব্ধ করে।


0

স্ট্যান্ডার্ড সি ++, 400 বাইট

এটি সংকলন করে g++ -g test.cpp -Wall -Wextra -pedantic -std=gnu++11

#include<map>
#include<cstring>
#define b ;break;case
#define u unsigned long long
std::map<std::string,u>V;void r(char*s){char*p,*q,*e;for(u c;*s;s=p){p=strpbrk(s,"^<?!");c=*p;*p++=0;switch(c){b'^':V[s]++b'<':for(e=p,c=0;*e!='>'||c;e++)c+=(*e=='<')-(*e=='>');*e++=0;while(V[s]>0){V[s]--;r(q=strdup(p));free(q);}p=e;b'?':scanf("%llu",&V[s])b'!':printf("%llu",V[s]);}}}int main(int,char*v[]){r(v[1]);}

আমি এটি আরও কিছুটা ছোট করতে সক্ষম হতে পারি। আপনার কিছু পরামর্শ থাকলে কমেন্ট করে জানাবেন।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.