سؤال

الأحجية

لغز صغير سمعته عندما كنت في المدرسة الثانوية يدور حول شيء من هذا القبيل ...

  • كان السائل يطلب مني أن أعطيه رقما؛
  • عند سماع الرقم، يقوم السائل بإجراء نوع من التحويل عليه بشكل متكرر (على سبيل المثال، قد يقول عشرة هي ثلاثة) حتى يصل في النهاية إلى الرقم 4 (وعندها سينتهي بـ أربعة هو السحر).
  • يبدو أن أي رقم قابل للتحويل إلى أربعة في النهاية، مهما حدث.

كان الهدف هو محاولة اكتشاف وظيفة التحويل ثم التمكن من مراقبة هذا اللغز بنفسك بشكل موثوق.

الحل

كانت وظيفة التحويل في أي خطوة

  • خذ الرقم المعني
  • حساب عدد الأحرف في تمثيل الكلمة الإنجليزية، وتجاهل الواصلة أو المسافات أو "و" (على سبيل المثال، "ten" تحتوي على 3 أحرف، "thirty-four" تحتوي على 10 أحرف، "مائة وثلاثة وأربعون" فيه 20 حرفًا).
  • إرجاع هذا العدد من الحروف.

بالنسبة لجميع الأرقام التي اهتممت باختبارها، فإن هذا يتقارب إلى 4.نظرًا لأن "أربعة" تحتوي أيضًا على أربعة أحرف، فسيكون هناك حلقة لا نهائية هنا؛بدلاً من ذلك يشار إليه فقط باسم سحر حسب الاتفاقية لإنهاء التسلسل.

التحدي

التحدي الذي يواجهك هو إنشاء جزء من التعليمات البرمجية التي ستقرأ رقمًا من المستخدم ثم تطبع أسطرًا توضح وظيفة التحويل التي يتم تطبيقها بشكل متكرر حتى يتم الوصول إلى "الأربعة سحرية".

خاصة:

  1. يجب أن تكون الحلول برامج كاملة في حد ذاتها.لا يمكن أن تكون مجرد وظائف تأخذ رقمًا - عاملًا في الإدخال.
  2. يجب قراءة الإدخال من الإدخال القياسي.(التوصيل من "الصدى" أو استخدام إعادة توجيه الإدخال أمر جيد نظرًا لأن ذلك ينتقل أيضًا من stdin)
  3. يجب أن يكون الإدخال في شكل رقمي.
  4. يجب طباعة سطر لكل تطبيق لدالة التحويل: a is b., ، حيث a و b عبارة عن أشكال رقمية للأرقام في التحويل.
  5. التوقف الكامل (فترات) مطلوبة!
  6. ومن الطبيعي أن يقول السطر الأخير، 4 is magic..
  7. يجب أن ينتج الكود الإخراج الصحيح لجميع الأرقام من 0 إلى 99.

أمثلة:

> 4
4 is magic.

> 12
12 is 6.
6 is 3.
3 is 5.
5 is 4.
4 is magic.

> 42
42 is 8.
8 is 5.
5 is 4.
4 is magic.

> 0
0 is 4.
4 is magic.

> 99
99 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.

الفائز هو أقصر إرسال حسب عدد أحرف الكود المصدري وهو ايضا صحيح.

علاوة

يمكنك أيضًا محاولة كتابة نسخة من الكود الذي يطبع الأسماء الإنجليزية للأرقام مع كل تطبيق لوظيفة التحويل.لا يزال الإدخال الأصلي رقميًا، ولكن يجب أن تحتوي خطوط الإخراج على شكل كلمة للرقم.

(مكافأة مضاعفة لرسم الأشكال باستخدام الكود الخاص بك)

(يحرر) بعض التوضيحات:

  1. أريد أن تظهر الكلمة على كلا الجانبين في جميع الحالات القابلة للتطبيق، على سبيل المثال. Nine is four. Four is magic.
  2. ومع ذلك، لا أهتم بالأحرف الكبيرة.ولا يهمني كيفية فصل الكلمات المميزة، على الرغم من أنه يجب فصلها: ninety-nine على ما يرام، ninety nine على ما يرام، ninetynine ليس بخير.

أنا أعتبر هذه فئة منفصلة للمنافسة الإضافية فيما يتعلق بالتحدي، لذا إذا اخترت هذا، فلا تقلق بشأن أن يكون الكود الخاص بك أطول من الإصدار الرقمي.

لا تتردد في تقديم حل واحد لكل إصدار.

هل كانت مفيدة؟

المحلول

جولف سكريبت - 101 96 93 92 91 90 94 86 بايت

90 → 94:إخراج ثابت لمضاعفات 10.
94 → 86:كود إعادة الهيكلة.استخدام الأساس 100 لإزالة الأحرف غير القابلة للطباعة.
86 → 85:يلقي أقصر على السلسلة.

{n+~."+#,#6$DWOXB79Bd")base`1/10/~{~2${~1$+}%(;+~}%++=" is "\".
"1$4$4-}do;;;"magic."

نصائح أخرى

بيرل، حوالي 147 حرفًا

يعتمد بشكل فضفاض على حل Platinum Azure:

               chop
              ($_.=
              <>);@
             u="433
            5443554
           366  887
          798   866
         555    766
        "=~     /\d
       /gx      ;#4
      sub       r{4
     -$_        ?$_
    <20         ?$u
   [$_          ]:(
  $'?           $u[
 $']            :0)
+$u[18+$&]:magic}print"
$_ is ",$_=r(),'.'while
                /\d
                /x;
                444

اللثغة المشتركة 157 حرفًا

إصدار جديد أكثر توافقًا، يقرأ الآن المدخلات القياسية ويتجاهل المسافات والواصلات:

(labels((g (x)(if(= x 4)(princ"4 is magic.")(let((n(length(remove-if(lambda(x)(find x" -"))(format nil"~r"x)))))(format t"~a is ~a.~%"x n)(g n)))))(g(read)))

في شكل يمكن قراءته بواسطة الإنسان:

 (labels ((g (x)
           (if (= x 4)
            (princ "4 is magic.")
            (let ((n (length (remove-if (lambda(x) (find x " -"))
                                        (format nil "~r" x)))))
               (format t"~a is ~a.~%" x n)
               (g n)))))
    (g (read)))

وبعض الاختبارات:

>24
24 is 10.
10 is 3.
3 is 5.
5 is 4.
4 is magic.

>23152436
23152436 is 64.
64 is 9.
9 is 4.
4 is magic.

والنسخة الإضافية تحتوي على 165 حرفًا:

 (labels((g(x)(if(= x 4)(princ"four is magic.")(let*((f(format nil"~r"x))(n(length(remove-if(lambda(x)(find x" -"))f))))(format t"~a is ~r.~%"f n)(g n)))))(g(read)))

إعطاء

>24
twenty-four is ten.
ten is three.
three is five.
five is four.
four is magic.

>234235
two hundred thirty-four thousand two hundred thirty-five is forty-eight.
forty-eight is ten.
ten is three.
three is five.
five is four.
four is magic.

بايثون 2.x، 144 150 154 166 حرف

هذا يقسم العدد إلى عشرات وآحاد ويجمعهم.الخاصية غير المرغوب فيها للمشغل الثلاثي الزائف a and b or c الذي - التي c يتم إرجاعها إذا b هو 0 يتم إساءة استخدامه هنا.

n=input()
x=0x4d2d0f47815890bd2
while n-4:p=n<20and x/10**n%10or 44378/4**(n/10-2)%4+x/10**(n%10)%10+4;print n,"is %d."%p;n=p
print"4 is magic."

النسخة الساذجة السابقة (150 حرفًا).فقط قم بتشفير جميع الأطوال كعدد صحيح.

n=input()
while n-4:p=3+int('1yrof7i9b1lsi207bozyzg2m7sclycst0zsczde5oks6zt8pedmnup5omwfx56b29',36)/10**n%10;print n,"is %d."%p;n=p
print"4 is magic."

ج - مع الكلمات العددية

445 431 427 421 399 386 371 359* 356 354 348 347 حرفا

هذا كل شيء.لا أعتقد أنني أستطيع جعل هذا أقصر.

جميع الأسطر الجديدة مخصصة لسهولة القراءة ويمكن إزالتها:

i;P(x){char*p=",one,two,three,four,five,six,sM,eight,nine,tL,elM,twelve,NP,4P,
fifP,6P,7P,8O,9P,twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,en,evL,thir,eL,tO,ty, is ,.\n,
4RmagicS,zero,";while(x--)if(*++p-44&&!x++)*p>95|*p<48?putchar(*p),++i:P(*p-48);
}main(c){for(scanf("%d",&c);c+(i=-4);P(34),P(c=i),P(35))P(c?c>19?P(c/10+18),
(c%=10)&&putchar(45):0,c:37);P(36);}

أدناه، هو غير مصغر إلى حد ما، ولكن لا يزال من الصعب قراءته.انظر أدناه للحصول على نسخة أكثر قابلية للقراءة.

i;
P(x){
    char*p=",one,two,three,four,five,six,sM,eight,nine,tL,elM,twelve,NP,4P,fifP,6P,7P,8O,9P,twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,en,evL,thir,eL,tO,ty, is ,.\n,4RmagicS,zero,";
    while(x--)
        if(*++p-44&&!x++)
            *p>95|*p<48?putchar(*p),++i:P(*p-48);
}
main(c){
    for(scanf("%d",&c);c+(i=-4);P(34),P(c=i),P(35))
        P(c?
            c>19?
                P(c/10+18),
                (c%=10)&&
                    putchar(45)
            :0,
            c
        :37);
    P(36);
}

توسعت وعلقت:

int count; /* type int is assumed in the minified version */

void print(int index){ /* the minified version assumes a return type of int, but it's ignored */
    /* see explanation of this string after code */
    char *word =
        /* 1 - 9 */
        ",one,two,three,four,five,six,sM,eight,nine,"
        /* 10 - 19 */
        "tL,elM,twelve,NP,4P,fifP,6P,7P,8O,9P,"
        /* 20 - 90, by tens */
        "twLQ,NQ,forQ,fifQ,6Q,7Q,8y,9Q,"
        /* lookup table */
        "en,evL,thir,eL,tO,ty, is ,.\n,4RmagicS,zero,";

    while(index >= 0){
        if(*word == ',')
            index--;
        else if(index == 0) /* we found the right word */
            if(*word >= '0' && *word < 'a') /* a compression marker */
                print(*word - '0'/*convert to a number*/);
            else{
                putchar(*word); /* write the letter to the output */
                ++count;
            }
        ++word;
    }
}
int main(int argc, char **argv){ /* see note about this after code */
    scanf("%d", &argc); /* parse user input to an integer */

    while(argc != 4){
        count = 0;
        if(argc == 0)
            print(37/*index of "zero"*/);
        else{
            if(argc > 19){
                print(argc / 10/*high digit*/ + 20/*offset of "twenty"*/ - 2/*20 / 10*/);
                argc %= 10; /* get low digit */

                if(argc != 0) /* we need a hyphen before the low digit */
                    putchar('-');
            }
            print(argc/* if 0, then nothing is printed or counted */);
        }
        argc = count;
        print(34/*" is "*/);
        print(argc); /* print count as word */
        print(35/*".\n"*/);
    }
    print(36/*"four is magic.\n"*/);
}

حول السلسلة المشفرة بالقرب من البداية

يتم ضغط أسماء الأرقام باستخدام مخطط بسيط للغاية.يتم استبدال السلاسل الفرعية المستخدمة بشكل متكرر بمؤشرات مكونة من حرف واحد في مصفوفة الأسماء.تتم إضافة "جدول بحث" لإدخالات الأسماء الإضافية إلى النهاية للسلاسل الفرعية غير المستخدمة بالكامل في المجموعة الأولى.عمليات البحث متكررة:يمكن أن تشير الإدخالات إلى إدخالات أخرى.

على سبيل المثال، الاسم المضغوط لـ 11 هو elM.ال print() وظيفة إخراج الأحرف e و l (الحرف الصغير 'L'، وليس الرقم '1') حرفيًا، ولكن بعد ذلك يعثر على M, ، لذلك يطلق على نفسه اسم فهرس الإدخال التاسع والعشرين (ASCII 'M' - ASCII '0') في جدول البحث.هذه السلسلة هي evL, ، لذلك يخرج e و v, ، ثم يطلق على نفسه مرة أخرى فهرس الإدخال الثامن والعشرين في جدول البحث، وهو en, ، ويتم إخراجه حرفيًا.وهذا مفيد لأن en يستخدم أيضا في eL ل een (يستخدم بعد eight في eighteen)، والذي يستخدم في tO ل teen (تستخدم لبعضها البعض -teen اسم).

يؤدي هذا المخطط إلى ضغط كبير إلى حد ما لأسماء الأرقام، بينما لا يتطلب سوى كمية صغيرة من التعليمات البرمجية لفك الضغط.

تمثل الفواصل الموجودة في بداية السلسلة ونهايتها الطريقة المبسطة التي يتم بها العثور على السلاسل الفرعية داخل هذه السلسلة.تؤدي إضافة حرفين هنا إلى حفظ المزيد من الأحرف لاحقًا.

حول إساءة استخدام main()

argv تم تجاهله (وبالتالي لم يتم الإعلان عنه في النسخة المضغوطة)، يتم تجاهل قيمة argc، ولكن يتم إعادة استخدام وحدة التخزين للاحتفاظ بالرقم الحالي.هذا يوفر علي فقط من الاضطرار إلى الإعلان عن متغير إضافي.

حول عدم وجود #include

سوف يشكو البعض من هذا الحذف #include <stdio.h> هو الغش.ليس كذلك على الإطلاق.المعطى هو برنامج C قانوني تمامًا سيتم تجميعه بشكل صحيح على أي مترجم C أعرفه (وإن كان ذلك مع تحذيرات).نظرًا لعدم وجود نماذج أولية لوظائف stdio، سيفترض المترجم أنها وظائف cdecl عائدة int, ، وسوف تثق في أنك تعرف ما هي الحجج التي يجب تمريرها.يتم تجاهل قيم الإرجاع في هذا البرنامج، على أي حال، وهي جميعها وظائف cdecl ("اتفاقية الاتصال C")، ونحن نعرف بالفعل ما هي الوسائط التي يجب تمريرها.

انتاج |

الإخراج كما هو متوقع:

0
zero is four.
four is magic.
1
one is three.
three is five.
five is four.
four is magic.
4
four is magic.
20
twenty is six.
six is three.
three is five.
five is four.
four is magic.
21
twenty-one is nine.
nine is four.
four is magic.

* غاب الإصدار السابق عن العلامة في جزأين من المواصفات:لم يتعامل مع الصفر، واحتاج إلى إدخال في سطر الأوامر بدلاً من stdin.أدت معالجة الأصفار إلى إضافة أحرف، ولكن استخدام stdin بدلاً من وسيطات سطر الأوامر، بالإضافة إلى بعض التحسينات الأخرى، أدى إلى حفظ نفس العدد من الأحرف، مما أدى إلى الغسل.

تم تغيير المتطلبات لتوضيح أنه يجب طباعة الكلمة الرقمية على جانبي "is".يلبي هذا الإصدار الجديد هذا المطلب، وينفذ المزيد من التحسينات من أجل (أكثر من) حساب الحجم الإضافي الضروري.

ي، 107 112 الشخصيات

'4 is magic.',~}:('.',~":@{.,' is ',":@{:)"1]2&{.\.
(]{&(#.100 4$,#:3 u:ucp'䌵䐵吶梇禈榛ꪛ멩鮪鮺墊馊꥘誙誩墊馊ꥺ겻곋榛ꪛ멩鮪鮺'))^:a:

(الخط الجديد لسهولة القراءة فقط)

الاستخدام والإخراج:

    '4 is magic.',~}:('.',~":@{.,' is ',":@{:)"1]2&{.\.(]{&(#.100 4$,#:3 u:ucp'䌵䐵吶梇禈榛ꪛ멩鮪鮺墊馊꥘誙誩墊馊ꥺ겻곋榛ꪛ멩鮪鮺'))^:a:12
12 is 6.    
6 is 3.     
3 is 5.     
5 is 4.     
4 is magic. 

تي إس كيو إل، 413 451 499 حرف

CREATE FUNCTION d(@N int) RETURNS int AS BEGIN
Declare @l char(50), @s char(50)
Select @l='0066555766',@s='03354435543668877987'
if @N<20 return 0+substring(@s,@N+1,1) return 0+substring(@l,(@N/10)+1,1) + 0+(substring(@s,@N%10+1,1))END
GO
CREATE proc M(@x int) as BEGIN
WITH r(p,n)AS(SELECT p=@x,n=dbo.d(@x) UNION ALL SELECT p=n,n=dbo.d(n) FROM r where n<>4)Select p,'is',n,'.' from r print '4 is magic.'END

(لا يعني ذلك أنني أقترح جديًا أن تفعل هذا ...حقًا أردت فقط أن أكتب CTE)

ليستخدم:

M 95

عائدات

p                n
----------- ---- -----------
95          is   10.
10          is   3.
3           is   5.
5           is   4.
4 is magic.

جافا (مع النموذجي)، 308 290 286 282 280 حرفا

class A{public static void main(String[]a){int i=4,j=0;for(;;)System.out.printf("%d is %s.%n",i=i==4?new java.util.Scanner(System.in).nextInt():j,i!=4?j="43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:".charAt(i)-48:"magic");}}

أنا متأكد من أن جروفي سيتخلص من الكثير من ذلك.

شرح وتنسيق (تمت إزالة جميع التعليقات والأسطر الجديدة والمسافات البيضاء البادئة/اللاحقة في العدد):

إلى حد معقول إلى الأمام على التوالي، ولكن

//boilerplate
class A{
   public static void main(String[]a){
      //i is current/left number, j right/next number.  i=4 signals to start
      //by reading input
      int i=4,j=0;
      for(;;)
         //print in the form "<left> is <right>."
         System.out.printf(
            "%d is %s.%n",
            i=i==4?
               //<left>: if i is 4 <left> will be a new starting number
               new java.util.Scanner(System.in).nextInt():
               //otherwise it's the next val
               j,
            i!=4?
               //use string to map number to its length (:;< come after 9 in ASCII)
               //48 is value of '0'.  store in j for next iteration
               j="43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:".charAt(i)-48:
               //i==4 is special case for right; print "magic"
               "magic");
   }
}

يحرر:لم تعد تستخدم ست عشرية، وهذا أقل ضغطات المفاتيح

ويندوز بوويرشيل:152 153 184 بايت

بناءً على الحل السابق، مع تأثير أكبر من الحلول الأخرى

$o="03354435543668877988"
for($input|sv b;($a=$b)-4){if(!($b=$o[$a])){$b=$o[$a%10]-48+"66555766"[($a-$a%10)/10-2]}$b-=48-4*!$a
"$a is $b."}'4 is magic.'

ج، 158 حرفًا

main(n,c){char*d="03354435543668877988";for(scanf("%d",&n);n-4;n=c)printf("%d is %d.\n",n,c=n?n<19?d[n]-48:d[n%10]-"_,**+++)**"[n/10]:4);puts("4 is magic.");}

(استنادًا في الأصل إلى كود Vlad's Python، تم استعارة خدعة من حل Tom Sirgedas' C++ للضغط على بضعة أحرف أخرى)

نسخة موسعة:

main(n, c) {
    char *d = "03354435543668877988";
    for (scanf("%d",&n); n-4; n = c)
        printf("%d is %d.\n", n, c = n ? n<19 ? d[n]-48 : d[n%10] - "_,**+++)**"[n/10]  : 4);
    puts("4 is magic.");
}

بايثون، 129 133 137 148 حرف

كإحماء، إليك نسختي الأولى (تحسن بضعة أحرف مقارنة بأفضل لغة Python السابقة).

ملاحظة.بعد بعض التنقيحات أصبح الآن أقصر بحوالي عشرين حرفًا:

n=input()
while n-4:p=(922148248>>n/10*3&7)+(632179416>>n%10*3&7)+(737280>>n&1)+4*(n<1);print n,'is %d.'%p;n=p
print'4 is magic.'

ج#:210 حرفا.

سحق:

using C=System.Console;class B{static void Main(){int
x=0,y=int.Parse(C.ReadLine());while(x!=4)C.Write((x=y)+" is {0}.\n",x==4?"magic":""+(y=x==0?4:"03354435543668877988"[x<20?x:x%10]+"0066555766"[x/10]-96));}}

موسع:

using C=System.Console;
class B
{
    static void Main()
    {
        int x=0,y=int.Parse(C.ReadLine());
        while(x!=4)
            C.Write((x=y)+" is {0}.\n",
                x==4?
                     "magic":
                     ""+(y= x==0?
                                4:
                                "03354435543668877988"[x<20?x:x%10]+
                                "0066555766"[x/10]-96)
                   );
    }
}

الحيل التي يستخدمها هذا الأسلوب:

  • قم بإنشاء جدول بحث لأطوال أسماء الأرقام بناءً على الأرقام التي تظهر في الرقم.
  • استخدم البحث عن مصفوفة الأحرف على سلسلة ما، وحساب الأحرف بدلاً من المصفوفة الرقمية.
  • استخدم الاسم المستعار لاسم الفئة للاختصار Console. ل C.
  • استخدم العامل الشرطي (الثلاثي) (?:) بدلاً من if/else.
  • استخدم ال \n مع Write رمز الهروب بدلا من WriteLine
  • استخدم حقيقة أن C# لديه ترتيب محدد للتقييم للسماح بالمهام داخل Write استدعاء وظيفة
  • استخدم تعبيرات الإسناد لإزالة العبارات الإضافية، وبالتالي الأقواس الزائدة

بيرل:148 حرفا

(بيرل: 233 181 212 206 200 199 198 185 179 149 148 حرفًا)

  • تم نقل تجزئة الاستثناءات إلى صفيف الوحدة.أدى ذلك إلى قدرتي على قطع الكثير من الشخصيات :-)
  • أشار mobrule إلى خطأ سيئ.يضيف الإصلاح السريع 31 حرفًا، حسنًا!
  • تمت إعادة تصميمها من أجل عدم وجود حالة خاصة، كما تم لعب الجولف الخفيف أيضًا.
  • الوصول المباشر إلى القائمة للاستخدام الفردي بدلاً من تخزينها في المصفوفة؟الجحيم نعم!
  • الكثير من إعادة البناء لشخصية دموية واحدة فقط.هذه حقًا هي حياة لاعب الجولف.:-(
  • عفوًا، إصلاح المسافة البيضاء سهل.198 الآن.
  • إعادة صياغة بعض التعليمات البرمجية الزائدة عن الحاجة.
  • آخر كلمة رئيسية عائدة في r غير ضروري، حلق بعض أكثر قبالة.
  • إعادة هيكلة ضخمة لكل تعليق؛لسوء الحظ، لم أتمكن من الوصول إلا إلى 149 لأنه كان علي إصلاح خطأ كان موجودًا في كل من الكود السابق وإصدارات المعلقين.
  • محاولة كلمة "السحر" العارية.

دعونا نبدأ هذه الكرة بمحاولة متواضعة في لغة بيرل.

@u=split'','4335443554366887798866555766';$_=<>;chop;print"$_ is ".($_=$_==4?0:$_<20?$u[$_]:($u[$_/10+18]+($_%10&&$u[$_%10]))or magic).".
"while$_

الخدع:

كثيرة جدا!

جافا سكريبت 1.8 (SpiderMonkey) - 153 حرفًا

l='4335443554366887798866555766'.split('')
for(b=readline();(a=+b)-4;print(a,'is '+b+'.'))b=a<20?l[a]:+l[18+a/10|0]+(a%10&&+l[a%10])
print('4 is magic.')

الاستخدام: echo 42 | js golf.js

انتاج:

42 is 8.
8 is 5.
5 is 4.
4 is magic.

مع مكافأة - 364 حرفًا

l='zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen twenty thirty fourty fifty sixty seventy eighty ninety'.split(' ')
z=function(a)a<20?l[a]:l[18+a/10|0]+(a%10?' '+l[a%10]:'')
for(b=+readline();(a=b)-4;print(z(a),'is '+z(b)+'.'))b=z(a).replace(' ','').length
print('four is magic.')

انتاج:

ninety nine is ten.
ten is three.
three is five.
five is four.
four is magic.

هاسكل، 224 270 الشخصيات

o="43354435543668877988"
x!i=read[x!!i]
n x|x<20=o!x|0<1="0066555766"!div x 10+o!mod x 10
f x=zipWith(\a b->a++" is "++b++".")l(tail l)where l=map show(takeWhile(/=4)$iterate n x)++["4","magic"]
main=readLn>>=mapM putStrLn.f

وأكثر قابلية للقراءة قليلاً -

ones = [4,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8]
tens = [0,0,6,6,5,5,5,7,6,6]

n x = if x < 20 then ones !! x else (tens !! div x 10) + (ones !! mod x 10)

f x = zipWith (\a b -> a ++ " is " ++ b ++ ".") l (tail l)
    where l = map show (takeWhile (/=4) (iterate n x)) ++ ["4", "magic"]
    
main = readLn >>= mapM putStrLn . f

إصدار C++ Stdio، المصغر:196 حرفا

#include <cstdio>
#define P;printf(
char*o="43354435543668877988";main(int p){scanf("%d",&p)P"%d",p);while(p!=4){p=p<20?o[p]-48:"0366555966"[p/10]-96+o[p%10]P" is %d.\n%d",p,p);}P" is magic.\n");}

إصدار C++ Iostreams، المصغر:195 حرفا

#include <iostream>
#define O;std::cout<<
char*o="43354435543668877988";main(int p){std::cin>>p;O p;while(p!=4){p=p<20?o[p]-48:"0366555966"[p/10]-96+o[p%10]O" is "<<p<<".\n"<<p;}O" is magic.\n";}

أصلي، غير مصغر:344 حرفا

#include <cstdio>

int ones[] = { 4, 3, 3, 5, 4, 4, 3, 5, 5, 4, 3, 6, 6, 8, 8, 7, 7, 9, 8, 8 };
int tens[] = { 0, 3, 6, 6, 5, 5, 5, 9, 6, 6 };

int n(int n) {
    return n<20 ? ones[n] : tens[n/10] + ones[n%10];
}

int main(int p) {
    scanf("%d", &p);
    while(p!=4) {
        int q = n(p);
        printf("%i is %i\n", p, q);
        p = q;
    }
    printf("%i is magic\n", p);
}

دلفي:329 حرفا

نسخة سطر واحد:

program P;{$APPTYPE CONSOLE}uses SysUtils;const S=65;A='EDDFEEDFFEDGGIIHHJII';B='DGGFFFJGG';function Z(X:Byte):Byte;begin if X<20 then Z:=Ord(A[X+1])-S else Z:=(Ord(B[X DIV 10])-S)+Z(X MOD 10)end;var X,Y:Byte;begin Write('> ');ReadLn(X);repeat Y:=Z(X);WriteLn(Format('%d is %d.',[X,Y]));X:=Y;until X=4;WriteLn('4 is magic.');end.

منسق:

program P;

{$APPTYPE CONSOLE}

uses
  SysUtils;

const
  S = 65;
  A = 'EDDFEEDFFEDGGIIHHJII';
  B = 'DGGFFFJGG';

function Z(X:Byte):Byte;
begin
  if X<20
  then Z := Ord(A[X+1])-S
  else Z := (Ord(B[X DIV 10])-S) + Z(X MOD 10);
end;

var
  X,Y: Byte;

begin
  Write('> ');
  ReadLn(X);

  repeat
    Y:=Z(X);
    WriteLn(Format('%d is %d.' , [X,Y]));
    X:=Y;
  until X=4;

  WriteLn('4 is magic.');
end.

ربما هناك مجال لمزيد من الضغط...:-ص

ج # 314 286 283 274 289 273 252 حرفًا.

سحق:

252 

طبيعي:

using C = System.Console;
class P
{
    static void Main()
    {
        var x = "4335443554366877798866555766";
        int m, o, v = int.Parse(C.ReadLine());
        do {
            C.Write("{0} is {1}.\n", o = v, v == 4 ? (object)"magic" : v = v < 20 ? x[v] - 48 : x[17 + v / 10] - 96 + ((m = v % 10) > 0 ? x[m] : 48));
        } while (o != 4);
        C.ReadLine();
    }
}

تحرير ديكام:فعلت بعض الإدراج والتغييرات متأنية:

  • تم تغيير l.ToString() إلى طاقم الممثلين object التابع string "magic".
  • تم إنشاء متغير مؤقت o, ، حتى أتمكن من تحريك break خارج for حلقة، وهذا هو، مما أدى إلى do-while.
  • مضمنة o المهمة، وكذلك v المهمة، والاستمرار في إدراج حساب l في وسيطات الوظيفة تمامًا، مما يزيل الحاجة إلى l.كما أدرجت مهمة m.
  • تمت إزالة مساحة في int[] x, int[]x شرعي أيضا.
  • حاولت تحويل المصفوفة إلى تحويل سلسلة، ولكن using System.Linq كان أكثر من اللازم لجعل هذا تحسنا.

تحرير 2 ديكامتم تغيير المصفوفة int إلى مصفوفة/سلسلة char، وإضافة العمليات الحسابية المناسبة لتصحيح ذلك.

لوا، 176 حرفًا

o={[0]=4,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7,7,9,8,8}t={3,6,6,5,5,5,7,6,6}n=0+io.read()while n~=4 do a=o[n]or o[n%10]+t[(n-n%10)/10]print(n.." is "..a..".")n=a end print"4 is magic."

أو

  o={[0]=4,3,3,5,4,4
  ,3,5,5,4,3,6,6,8,8
  ,7,7,9,8,8}t={3,6,
   6,5,5,5,7,6,6}n=
   0+io.read()while
   n ~= 4 do a= o[n
   ]or o[n%10]+t[(n
   -n%10)/10]print(
n.." is "..a.."." )n=a
end print"4 is magic."

ج - بدون كلمات عددية

180 175* 172 167 حرفا

جميع الأسطر الجديدة مخصصة لسهولة القراءة ويمكن إزالتها:

i;V(x){return"\3#,#6$:WOXB79B"[x/2]/(x%2?1:10)%10;}main(c){for(scanf("%d",&c);
c-4;)i=c,printf("%d is %d.\n",i,c=c?c>19?V(c/10+19)+V(c%10):V(c):4);puts(
"4 is magic.");}

غير مصغر قليلا:

i;
V(x){return"\3#,#6$:WOXB79B"[x/2]/(x%2?1:10)%10;}
main(c){
    for(scanf("%d",&c);c-4;)
        i=c,
        printf("%d is %d.\n",i,c=c?c>19?V(c/10+19)+V(c%10):V(c):4);
    puts("4 is magic.");
}

* غاب الإصدار السابق عن العلامة في جزأين من المواصفات:لم يتعامل مع الصفر، واحتاج إلى إدخال في سطر الأوامر بدلاً من stdin.التعامل مع صفر أحرف مضافة، ولكن استخدام stdin بدلاً من وسيطات سطر الأوامر يوفر المزيد، مما يؤدي إلى توفير صافي.

بيرل, 123 122 حرفا

لقد أدركت للتو أنه لا توجد حاجة للإخراج إلى STDOUT، لذا قم بالإخراج إلى STDERR بدلاً من ذلك وقم بحذف حرف آخر.

@u='0335443554366887798866555766'=~/./g;$_+=<>;warn"$_ is ",$_=$_-4?$_<20?$u[$_]||4:$u[chop]+$u[$_+18]:magic,".\n"until/g/

والإصدار الذي يُرجع أرقامًا مكتوبة:

279 278 276 280 حرفا

@p=(Thir,Four,Fif,Six,Seven,Eigh,Nine);@n=("",One,Two,Three,Four,Five,@p[3..6],Ten,Eleven,Twelve,map$_.teen,@p);s/u//for@m=map$_.ty,Twen,@p;$n[8].=t;sub n{$n=shift;$n?$n<20?$n[$n]:"$m[$n/10-2] $n[$n%10]":Zero}$p+=<>;warnt$m=n($p)," is ",$_=$p-4?n$p=()=$m=~/\w/g:magic,".\n"until/c/

على الرغم من أن هذا يلبي المواصفات، إلا أنه ليس منسقًا بشكل جيد بنسبة 100%.تقوم بإرجاع مسافة إضافية بعد الأرقام المنتهية بالصفر.المواصفات تقول:

"لا يهمني كيفية فصل رموز الكلمات، على الرغم من أنه يجب فصلها"

هذا نوع من السهولة بالرغم من ذلك.نسخة أكثر صحة في

282 281 279 283 حرفا

@p=(Thir,Four,Fif,Six,Seven,Eigh,Nine);@n=("\x8",One,Two,Three,Four,Five,@p[3..6],Ten,Eleven,Twelve,map$_.teen,@p);s/u//for@m=map$_.ty,Twen,@p;$n[8].=t;sub n{$n=shift;$n?$n<20?$n[$n]:"$m[$n/10-2]-$n[$n%10]":Zero}$p+=<>;warn$m=n($p)," is ",$_=$p-4?n$p=()=$m=~/\w/g:magic,".\n"until/c/

بايثون:

#!/usr/bin/env python

# Number of letters in each part, we don't count spaces
Decades = ( 0, 3, 6, 6, 6, 5, 5, 7, 6, 6, 0 )
Smalls  = ( 0, 3, 3, 5, 4, 4, 3, 5, 5, 4 )
Teens  =  ( 6, 6, 8, 8, 7, 7, 9, 8, 8 )

def Count(n):
    if n > 10 and n < 20: return Teens[n-11]
    return   Smalls[n % 10 ] + Decades [ n / 10 ]

N = input()

while N-4:
    Cnt = Count(N)
    print "%d is %d" % ( N, Cnt)
    N = Cnt

print "4 is magic"

C++، 171 حرفًا (تم حذف #include)

void main(){char x,y,*a="03354435543668877988";scanf("%d",&x);for(;x-4;x=y)y=x?x<19?a[x]-48:"_466555766"[x/10]+a[x%10]-96:4,printf("%d is %d.\n",x,y);puts("4 is magic.");}

روبي، 164 حرفًا

n=gets.to_i;s="03354435543668877987";if n==0;puts"0 is 4.";else;puts"#{n} is #{n=(n<20)?s[n]-48:"0066555766"[n/10]-48+s[n%10]-48}." until n==4;end;puts"4 is magic."

فك التشفير:

n = gets.to_i
s = "03354435543668877987"
if n == 0
  puts "0 is 4."
else
  puts "#{n} is #{n = (n < 20) ? s[n] - 48 : "0066555766"[n / 10] - 48 + s[n % 10] - 48}." until n == 4
end

puts "4 is magic."

لوا 185 190 199

تمت إضافة فترات، وإضافة io.read، وإزالة () من الطباعة الأخيرة

 n=io.read();while(n~=4)do m=('43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:'):sub(n+1):byte()-48;print(n,' is ',m,'.')n=m;end print'4 is magic.'

مع فواصل الأسطر

 n=io.read()
 while (n~=4) do
    m=('43354435543668877988699;::9;;:699;::9;;:588:998::9588:998::9588:998::97::<;;:<<;699;::9;;:699;::9;;:'):sub(n+1):byte()-48;
    print(n,' is ',m,'.')
    n=m;
 end 
 print'4 is magic.'

كود بي اتش بي

function get_num_name($num){  
    switch($num){  
        case 1:return 'one';  
    case 2:return 'two';  
    case 3:return 'three';  
    case 4:return 'four';  
    case 5:return 'five';  
    case 6:return 'six';  
    case 7:return 'seven';  
    case 8:return 'eight';  
    case 9:return 'nine';  
    }  
}  

function num_to_words($number, $real_name, $decimal_digit, $decimal_name){  
    $res = '';  
    $real = 0;  
    $decimal = 0;  

    if($number == 0)  
        return 'Zero'.(($real_name == '')?'':' '.$real_name);  
    if($number >= 0){  
        $real = floor($number);  
        $decimal = number_format($number - $real, $decimal_digit, '.', ',');  
    }else{  
        $real = ceil($number) * (-1);  
        $number = abs($number);  
        $decimal = number_format($number - $real, $decimal_digit, '.', ',');  
    }  
    $decimal = substr($decimal, strpos($decimal, '.') +1);  

    $unit_name[1] = 'thousand';  
    $unit_name[2] = 'million';  
    $unit_name[3] = 'billion';  
    $unit_name[4] = 'trillion';  

    $packet = array();    

    $number = strrev($real);  
    $packet = str_split($number,3);  

    for($i=0;$i<count($packet);$i++){  
        $tmp = strrev($packet[$i]);  
        $unit = $unit_name[$i];  
        if((int)$tmp == 0)  
            continue;  
        $tmp_res = '';  
        if(strlen($tmp) >= 2){  
            $tmp_proc = substr($tmp,-2);  
            switch($tmp_proc){  
                case '10':  
                    $tmp_res = 'ten';  
                    break;  
                case '11':  
                    $tmp_res = 'eleven';  
                    break;  
                case '12':  
                    $tmp_res = 'twelve';  
                    break;  
                case '13':  
                    $tmp_res = 'thirteen';  
                    break;  
                case '15':  
                    $tmp_res = 'fifteen';  
                    break;  
                case '20':  
                    $tmp_res = 'twenty';  
                    break;  
                case '30':  
                    $tmp_res = 'thirty';  
                    break;  
                case '40':  
                    $tmp_res = 'forty';  
                    break;  
                case '50':  
                    $tmp_res = 'fifty';  
                    break;  
                case '70':  
                    $tmp_res = 'seventy';  
                    break;  
                case '80':  
                    $tmp_res = 'eighty';  
                    break;  
                default:  
                    $tmp_begin = substr($tmp_proc,0,1);  
                    $tmp_end = substr($tmp_proc,1,1);  

                    if($tmp_begin == '1')  
                        $tmp_res = get_num_name($tmp_end).'teen';  
                    elseif($tmp_begin == '0')  
                        $tmp_res = get_num_name($tmp_end);  
                    elseif($tmp_end == '0')  
                        $tmp_res = get_num_name($tmp_begin).'ty';  
                    else{  
                        if($tmp_begin == '2')  
                            $tmp_res = 'twenty';  
                        elseif($tmp_begin == '3')  
                            $tmp_res = 'thirty';  
                        elseif($tmp_begin == '4')  
                            $tmp_res = 'forty';  
                        elseif($tmp_begin == '5')  
                            $tmp_res = 'fifty';  
                        elseif($tmp_begin == '6')  
                            $tmp_res = 'sixty';  
                        elseif($tmp_begin == '7')  
                            $tmp_res = 'seventy';  
                        elseif($tmp_begin == '8')  
                            $tmp_res = 'eighty';  
                        elseif($tmp_begin == '9')  
                            $tmp_res = 'ninety';  

                        $tmp_res = $tmp_res.' '.get_num_name($tmp_end);  
                    }  
                    break;  
            }  

            if(strlen($tmp) == 3){  
                $tmp_begin = substr($tmp,0,1);  

                $space = '';  
                if(substr($tmp_res,0,1) != ' ' && $tmp_res != '')  
                    $space = ' ';  

                if($tmp_begin != 0){  
                    if($tmp_begin != '0'){  
                        if($tmp_res != '')  
                            $tmp_res = 'and'.$space.$tmp_res;  
                    }  
                    $tmp_res = get_num_name($tmp_begin).' hundred'.$space.$tmp_res;  
                }  
            }  
        }else  
            $tmp_res = get_num_name($tmp);  
        $space = '';  
        if(substr($res,0,1) != ' ' && $res != '')  
            $space = ' ';  
        $res = $tmp_res.' '.$unit.$space.$res;  
    }  

    $space = '';  
    if(substr($res,-1) != ' ' && $res != '')  
        $space = ' ';  

    if($res)  
        $res .= $space.$real_name.(($real > 1 && $real_name != '')?'s':'');  

    if($decimal > 0)  
        $res .= ' '.num_to_words($decimal, '', 0, '').' '.$decimal_name.(($decimal > 1 && $decimal_name != '')?'s':'');  
    return ucfirst($res);  
}  

//////////// اختبارات ////////////////

 $str2num = 12;
    while($str2num!=4){
        $str = num_to_words($str2num, '', 0, '');  
        $str2num = strlen($str)-1;
        echo $str . '=' . $str2num .'<br/>';
        if ($str2num == 4)
            echo 'four is magic';
    }

////// نتائج /////////

Twelve =6
Six =3
Three =5
Five =4
four is magic

بيرل - 130 حرفًا


5.12.1   (130 حرفًا) 121 123 132 136 140

#        1         2         3         4         5         6         7         8         9        100        11        12        13       14    
#23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123

@u='4335443554366887798866555766'=~/./g;$_=pop;say"$_ is ",$_=$_-4?$_<20?$u[$_]:$u[$_/10+18]+(($_%=10)&&$u[$_]):magic,"."until/\D/


5.10.1   (134 حرفًا) 125 127 136 140 144

#        1         2         3         4         5         6         7         8         9        100        11        12        13       14    
#23456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234

@u='4335443554366887798866555766'=~/./g;$_=pop;print"$_ is ",$_=$_-4?$_<20?$u[$_]:$u[$_/10+18]+(($_%=10)&&$u[$_]):magic,".\n"until/\D/


تغيير التاريخ:

20100714:2223 - عاد التغيير على علم حكم الغوغاء, ، لكن ($_%10&&$u[$_%10])(($_%=10)&&$u[$_]), ، وهو نفس عدد الأحرف، لكنني فعلت ذلك في حالة رؤية شخص ما طريقة لتحسينه

20100714:0041 - split//,'...''...'=~/./g
20100714:0025 - ($_%10&&$u[$_%10])$u[$_%10]
20100713:2340 - while$_until/\D/ + إزالة الأقواس غير الضرورية
20100713:xxxx - $=<>;chop;$_=pop; - مجاملة ل حكم الغوغاء


ملحوظة: لقد سئمت من تحسين إجابات الآخرين في التعليقات، لذا فأنا الآن جشع ويمكنني فقط إضافة تغييراتي هنا :) هذا منفصل عن بلاتينيوم أزورإجابة - يرجع الفضل جزئيًا إلى هوبز, حكم الغوغاء, ، و بلاتينيوم أزور.

بيرل وقح مع عدد الكلمات (329 حرفًا)

مقتبس بشكل مباشر إلى حد ما من كود P Daddy's C، مع بعض التعديلات عليه p() لجعله يفعل نفس الشيء باستخدام عناصر Perl الأولية بدلاً من عناصر C، وحلقة رئيسية تمت إعادة كتابتها في الغالب.انظر له للحصول على تفسير.الخطوط الجديدة كلها اختيارية.

@t=(qw(zero one two three four five six sM eight nine
tL elM twelve NP 4P fifP 6P 7P 8O 9P twLQ NQ forQ fifQ
6Q 7Q 8y 9Q en evL thir eL tO ty 4SmagicT)," is ",".\n");
sub p{local$_=$t[pop];1while s/[0-Z]/$t[-48+ord$&]/e;
print;length}$_=<>;chop;while($_-4){
$_=($_>19?(p($_/10+18),$_&&print("-"),$_%=10)[0]:0)+p$_;
p 35;p$_;p 36}p 34

ملاحظة جانبية:انها سيئة للغاية أن بيرل print فقط تُرجع صحيح/خطأ؛إذا أعادت عددًا فسيوفر لي 7 ضربات.

روبي، 141 حرفًا:

n=gets.to_i;m="4335443554366887798866555766";loop{s=n;n=n>20?m[18+n/10]+m[n%10]-96: m[n]-48;puts"#{s} is #{n==s ? 'magic': n}.";n==s &&break}
while(true)
{
    string a;
    ReadLine(a)
    WriteLine(4);

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top