FizzBuzz в Brainfuck

Вдохновленный немного предыдущий вопрос о Brainfuck и недавний вторжение, я решил сделать FizzBuzz в Brainfuck.

Код полностью мой, за исключением включения Печать числа алгоритма, который я нашел в StackOverflow.

Мой код разделен на несколько частей.

  • Настройка . Создайте ленту, чтобы содержать некоторые данные.
  • Петля через все FizzBuzzes
  • Номер печати, если FizzBuzz не найден и печать новой строки

Было довольно сложно это сделать, я начал играть с основными операторами Brainfuck, чтобы создать основные инструменты, которые я мог бы использовать. После выяснения того, как «искать» значение на ленте, копировать /перемещать значение в другое место и некоторые другие полезные вещи, я решил пойти с этим подходом.


Лента

После раздела настройки это выглядит так:

Brainfuck tape

Сверху вниз это означает:

  • 100 = количество циклов цикла
  • 10 = символ новой строки
  • 255 = Маркер, чтобы найти начало
  • 0 = Счетчик, какое количество мы сейчас находимся.
  • 0 = Boolean, чтобы указать, найден ли FizzBuzz или нет (знать, следует ли печатать номер)
  • Пустое пространство для преобразования числа в строковый алгоритм

Тогда существует конфигурируемая последовательность:

  • 254 = Маркер для раздела FizzBuzz
  • 0 = Сколько итераций, которые были с последней печати
  • 3/5 = Сколько итераций, пока мы не напечатаем этот текст
  • Текст
  • Пустое пространство для указания конца текста

И наконец:

  • 254 = Маркер для раздела FizzBuzz
  • 253 = Конец последовательностей FizzBuzz

Подход в регулярном коде

Код не выполняет «классическую» модульную операцию на каждой итерации, вместо этого ее можно рассматривать как нечто вроде этого:

int fizz = 3;
int fizzUp = 0;
int buzz = 5;
int buzzUp = 0;
boolean printed = false;
for (int i = 1; i <= 100; i++) {
    printed = false;

    fizz--;
    fizzUp++;
    if (fizz == 0) {
        print("Fizz");
        printed = true;
        while (fizzUp > 0) {
            fizzUp--;
            fizz++;
        }
    }

    // Same for buzz as for fizz

    if (!printed) {
        print(i);
    }
    print("\n");
}

Основные вопросы

  • Является ли мой код Brainfuck несколько удобочитаемым? (Я знаю, я знаю, это Brainfuck ...) Я попытался добавить много комментариев, описывающих, что делает код (на этот раз я действительно думаю, что что более важно, чем почему ).
  • Я принял правильное решение структурировать ленту таким образом?
  • Может ли настройка текстов «Fizz» и «Buzz» быть более эффективной?
  • Можно ли сделать что-то еще более эффективным?
  • Любые другие комментарии оценены
 ++++++++++[>++++++++++<-]> Initialize 100 (number of times to perform FizzBuzz)

TAPE MEANINGS
255 Start
254 A Fizz or Buzz text to print
253 End of Fizzes and Buzzes
252 Currently processed FizzBuzz calculation

TAPE OVERVIEW
Remaining Iterations
10 for Line Break
255 Start Marker
Counter
Boolean 1 or 0 for whether or not a fizzbuzz matches current counter
Some empty space for converting counter to string
  Any Number of Sequences of the following
    254 Indicator for FizzBuzz sequence
    Counter
    Countdown until next text output
    Text any number of characters
    Zero
    Zero
254 and 253 marker to indicate the end of sequences


>++++++++++                   Line break
>-                            Start marker
>>>>>>>>>>>>>>>>              Empty space for counter to string conversion


SETUP Create the Fizz and Buzz sequences on the tape

FIZZ
-->                               Create indicator
+++++++[->++++++++++<]>           Create F
[->+>+>+>+<<<<]                   Copy 4x F
+++                               Set modulo operator to 3
>>+++>>>                          Adjust second letter to I
++++++++[-<++++<++++<++++>>>]     Make the last three lowercase to Fiff
+++++[-<++++<++++>>]              Modify the last two F to Z by adding 20
>>                                Leave two zeros at the end

BUZZ
-->                               Create indicator
++++++[->+++++++++++<]>           Create B
[->+>+>+>+<<<<]                   Copy 4x B
+++++                             Set modulo operator to 5
>>+>++++++>++++++>                Adjust BBBB to BCHH
++++++++[-<++++<++++<++++>>>]     Make lower case
++++++[-<+++<+++<+++>>>]          Adjust Bchh to Buzz
>>                                Leave two zeros at the end



-->---          Mark the ending with 254 and 253

END OF SETUP

ALGORITHM START

+[-<+]-         Go backwards to the 255 mark
<

[
 +[->+]-        Go forward to the start position 255 marker
 <<->>          Decrease countdown
 >+             Increase counter
 >[-]           Reset boolean for if we have found a match or not

 ++[-->++]-->   Find next 254 and go one step beyond it

                Loop through all 254s
    +++[---         Make sure that we are not at 253 (end)
     ++[--<++]--    Find last value 254
     --             Change marker to 252 to indicate that we're processing it
     >>             Go to the countdown
     -<             Decrease fizzbuzz countdown
     +>             Increase fizzbuzz counter

     If current marker is NOT zero
         [
             ++++[----<++++]--   Find value 252 and change to 254
             [>]                 Position to a place that is zero to avoid repeat
             ++[-->++]-- <       Find NEXT 254 marker and stop right before it
         ]

     >++
         Check if we are positioned on a 254 already then if skip this
         [--

             We have a match so find start position and mark match

             +[-<+]-  >>         Find 255 marker and go to the boolean
             [-]+                Set boolean to 1 whatever the previous value is
             ++++[---->++++]--   Find value 252 and change to 254
             >[->+<]             Reset the current FizzBuzz countdown
             >>[.>]              Print the text
             ++[-->++]           Go to next 254 change to 256 to break loop
         ]
     -->

     +++ # Detect if we are at the 253 end
     ]
  ---

ALL FIZZBUZZES PROCESSED
Use the boolean to check whether or not to print the number


  +[-<+]-     Go back to the 255 marker
  >>          Go to boolean
  -[          If boolean is zero then print the number
         +>>>
         +[-<+]-    Go back to the 255 marker
         >>          We are positioned after the counter
         Code taken from StackOverflow below for printing a number
>++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>>[-]>>>++++++++++<[->-[>+>>]>[+[-
<+>]>+>>]<<<<<]>[-]>>[>++++++[-<++++++++>]<.<<+>+>[-]]<[<[->-<]++++++[->++++++++
<]>.[-]]<<++++++[-<++++++++>]<.[-]<<[-<+>]
         End of StackOverflow code

         +[-<+]->>    Locate the 255 marker and goto the boolean
  ]+

  Boolean is always one here so print new line
  [-]<<<.>>>     Print new line

  +[-<+]-    Go back to the 255 marker
  <<         Go to the countdown to find out if we should go another round
]

Сжатая типичная версия Brainfuckish:

++++++++++[>++++++++++<-]>>++++++++++>->>>>>>>>>>>>>>>>-->+++++++[->++
++++++++<]>[->+>+>+>+<<<<]+++>>+++>>>++++++++[-<++++<++++<++++>>>]++++
+[-<++++<++++>>]>>-->++++++[->+++++++++++<]>[->+>+>+>+<<<<]+++++>>+>++
++++>++++++>++++++++[-<++++<++++<++++>>>]++++++[-<+++<+++<+++>>>]>>-->
---+[-<+]-<[+[->+]-<<->>>+>[-]++[-->++]-->+++[---++[--<++]---->>-<+>[+
+++[----<++++]--[>]++[-->++]--<]>++[--+[-<+]->>[-]+++++[---->++++]-->[
->+<]>>[.>]++[-->++]]-->+++]---+[-<+]->>-[+>>>+[-<+]->>>++++++++++<<[-
>+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>>[-]>>>++++++++++<[->-[>+>>]>[+[-<+>]>
+>>]<<<<<]>[-]>>[>++++++[-<++++++++>]<.<<+>+>[-]]<[<[->-<]++++++[->+++
+++++<]>.[-]]<<++++++[-<++++++++>]<.[-]<<[-<+>]+[-<+]->>]+[-]<<<.>>>+[
-<+]-<<]
80 голосов | спросил Simon Forsberg 18 J000000Friday14 2014, 15:22:57

3 ответа


41

Упрощения

Благодаря выполнению некоторого анализа циклов while в моем проекте Brainduck (который я работал, благодаря обзору «Привет, Brainfuck» ), мне удалось найти кучу циклов, которые всегда выполнялись x раз. Развернув эти петли (скопируйте их содержимое x раз и удалите цикл), возможно несколько упрощений.

Boolean peek-a-boo. Уилер - логический?

+[-<+]->>    Locate the 255 marker and goto the boolean

Этот цикл всегда выполняется ровно дважды, что означает, что цикл можно развернуть до +-<+-<+->>

Курсор
<<>>

Булевы всегда одни, без дерьма Шерлок!

cursor is now located on the boolean

Неудивительно, что логическое значение всегда одно, когда вы делали ]+ Boolean is always one here so print new line [-]<<<.>>> Print new line сразу после +. Поскольку значение всегда равно 1, цикл всегда выполняется один раз, что упрощает этот код:

]

Boolean, marker, boolean, Дамблдор!

]
Boolean is now zero so just print the new line
<<<.>>>     Print new line

«Мы позиционируем после счетчика» - это то же самое, что «мы позиционированы в булевом» (который теперь имеет значение 0). Этот код начинается с логического значения, которое расположено на два шага справа от маркера 255, а затем вы перемещаете три шага вправо только для возврата к маркеру 255 ... поскольку этот цикл для возврата назад всегда выполняется пять раз, это можно упростить. Сначала разверните цикл:

-[          If boolean is zero then print the number
     +>>>
     +[-<+]-    Go back to the 255 marker
     >>          We are positioned after the counter

Затем удалите +>>> +-<+-<+-<+-<+-<+- Go back to the 255 marker >> We are positioned after the counter , которые отменяют друг друга:

+-

Затем удалите +>>> <<<<< Go back to the 255 marker >> We are positioned after the counter , которые отменяют друг друга, и вот что осталось:

><

Поиск 252 и переход на 254

+

Этот цикл выполняется ровно дважды, что упрощается:

++++[----<++++]--   Find value 252 and change to 254

Поиск 254, когда мы уже там уже

<<++                Go left to value 252 and change to 254

Угадайте, что !? Ваш 253 расположен ровно на один шаг после значения 254, что означает, что цикл «Найти последнее значение 254» выполняется только один раз, что означает, что это время упрощения:

+++[---         Make sure that we are not at 253 (end)
   ++[--<++]--  Find last value 254

   --           Change marker to 252 to indicate that we're processing it

Перейдите непосредственно к обратному отсчету, не меняйте его, не забирайте $ 200

 +++[---         Make sure that we are not at 253 (end)
     <--         Go to 254 marker and change to 252 to indicate that we are processing it

Код BF >> Go to the countdown -< Decrease fizzbuzz countdown +> Increase fizzbuzz counter - это то же самое, что и >>-<+>, поэтому измените это на:

>+>-

Сброс логического

>+             Increase fizzbuzz counter
>-             Decrease fizzbuzz countdown

Логическое значение сбрасывается в конце каждого цикла, не нужно также перезапускать его в начале, а затем:

>+              Increase counter
>[-]            Reset boolean for if we have found a match or not

Поиск маркера 255 и обратного отсчета

>+>             Increase counter

В моем анализе было найдено что-то интересное: первый раз, когда был выполнен цикл «Перейти к маркеру начального положения 255», он выполнялся только один раз, но all в других случаях он выполнялся ровно в два раза. Это дало мне понять, что здесь есть возможность рефакторинга, начиная с простой замены синглаALGORITHM START +[-<+]- Go backwards to the 255 mark < [ +[->+]- Go forward to the start position 255 marker с <, чтобы сделать цикл всегда выполняться ровно дважды.

<<

Тогда мне пришло в голову, что в конце цикла, в этом коде:

+[-<+]-         Go backwards to the 255 mark
<<              Go to the countdown

[
    +[->+]-     Go forward to the start position 255 marker

Это «Вернуться к маркеру 255» всегда выполнялось дважды, а это означает, что мы еще раз расширяем и упрощаем:

<<<.>>>     Print new line

+[-<+]-    Go back to the 255 marker
<<         Go to the countdown to find out if we should go another round

, а затем:

<<<.>>>     Print new line

+-<+-<+-   Go back to the 255 marker
<<         Go to the countdown to find out if we should go another round

Теперь, возвращаясь к началу большой петли, давайте посмотрим:

<<<.      Print new line
<         Go to the countdown to find out if we should go another round

Учитывая, что первый [ +[->+]- Go forward to the start position 255 marker <<->> Decrease countdown всегда находится в обратном отсчете, мы можем просто сделать [), т. е. нам не нужно сначала точно оценивать маркер 255 чтобы перейти к обратному отсчету, когда мы уже находимся на обратном отсчете. Поэтому замените это на:

->>

Уточнение комментариев

[
  ->>            Decrease countdown

Комментарий «избегать повторения» не очень хорош, из-за цикла после этого достаточно сделать только [>] Position to a place that is zero to avoid repeat ++[-->++]-- < Find NEXT 254 marker and stop right before it один раз. Однако, если сама строка будет содержать магическое значение 254, тогда у нас возникнет проблема. Так уточните этот комментарий:

>

Использование памяти

Использование памяти кажется довольно хорошим, только 39 ячеек памяти используются в целом. Однако это:

[>]                 Go to a zero to avoid repeat in case there is a 254 value in the string

Не лишнее дополнительное пространство. Это можно уменьшить до:

>>>>>>>>>>>>>>>>              Empty space for counter to string conversion

Также обратите внимание, как пробелы каждые 5 инструкций делают ее более читаемой.

Дополнительные упрощения, которые уменьшают гибкость

Это упрощение может быть сделано только благодаря тому, что FizzBuzz заканчивается на 100. Если вы хотите FizzBuzz больше, вы не можете упростить эту часть.

Код SO для печати номера можно упростить до:

>>>>> >>>>> >

С помощью этого упрощения можно освободить одну дополнительную ячейку памяти, изменив ее на:

     Code taken from StackOverflow below for printing a number
>++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>>[-]>>>++++++++++<
[->->+<<]>[-]>[<++++++[->++++++++<]
>.[-]]<<++++++[-<++++++++>]<.[-]<<[-<+>]
     End of StackOverflow code

2 стать 1 (два нуля становятся одним)

В настоящее время всегда есть два нуля после строки Fizz или Buzz. Это можно легко изменить только на один ноль, что позволило бы немного упростить этот код:

>>>>> >>>>>                   Empty space for counter to string conversion

Это также позволяет упростить в конце случая «У нас есть соответствие»:

 If current marker is NOT zero
     [
         <<++                Go left to value 252 and change to 254
         [>]                 Go to a zero to avoid repeat in case there is a 254 value in the string
     ]

Это позволяет больше гибкости, хотя и иметь его, как было раньше, для сканирования следующего значения 254.

Результирующий код

Неинминированная версия полученного кода без дополнительных упрощающих гибкость упрощений, 631 Инструкция Brainfuck в исходном коде, 152267 выполняется во время выполнения:

>++                 Go to next 254 change to 256 to break loop

Минимизированная версия полученного кода с дополнительными упрощающими гибкостью упрощениями, 548 символов: (выполняются исполняемые команды выполнения143808)

TAPE MEANINGS
255 Start
254 A Fizz or Buzz text to print
253 End of Fizzes and Buzzes
252 Currently processed FizzBuzz calculation

TAPE OVERVIEW
Remaining Iterations
10 for Line Break
255 Start Marker
Counter
Boolean 1 or 0 for whether or not a fizzbuzz matches current counter
Some empty space for converting counter to string
  Any Number of Sequences of the following
    254 Indicator for FizzBuzz sequence
    Counter
    Countdown until next text output
    Text any number of characters
    Zero
    Zero
254 and 253 marker to indicate the end of sequences

++++++++++[>++++++++++<-]> Initialize 100 (number of times to perform FizzBuzz)


>++++++++++                   Line break
>-                            Start marker
>>>>> >>>>> >                 Empty space for counter to string conversion


SETUP Create the Fizz and Buzz sequences on the tape
  without having to write plus more than 65 times for every character

FIZZ
-->                               Create indicator
+++++++[->++++++++++<]>           Create F
[->+>+>+>+<<<<]                   Copy 4x F
+++                               Set modulo operator to 3
>>+++>>>                          Adjust second letter to I
++++++++[-<++++<++++<++++>>>]     Make the last three lowercase to Fiff
+++++[-<++++<++++>>]              Modify the last two F to Z by adding 20
>>                                Leave two zeros at the end

BUZZ
-->                               Create indicator
++++++[->+++++++++++<]>           Create B
[->+>+>+>+<<<<]                   Copy 4x B
+++++                             Set modulo operator to 5
>>+>++++++>++++++>                Adjust BBBB to BCHH
++++++++[-<++++<++++<++++>>>]     Make lower case
++++++[-<+++<+++<+++>>>]          Adjust Bchh to Buzz
>>                                Leave two zeros at the end



-->---          Mark the ending with 254 and 253

END OF SETUP

ALGORITHM START

+[-<+]-         Go backwards to the 255 mark
<<              Go to the countdown

[
 ->>            Decrease countdown
 >+>            Increase counter

 ++[-->++]-->   Find next 254 and go one step beyond it

                Loop through all 254s
    +++[---         Make sure that we are not at 253 (end)
     <--            Go to 254 marker and change to 252 to indicate that we are processing it
     >+             Increase fizzbuzz counter
     >-             Decrease fizzbuzz countdown

     If current marker is NOT zero
         [
             <<++                Go left to value 252 and change to 254
             [>]                 Go to a zero to avoid repeat in case there is a 254 value in the string
             ++[-->++]-- <       Find NEXT 254 marker and stop right before it
         ]

     >++
         Check if we are positioned on a 254 already then if skip this
         [--

             We have a match so find start position and mark match

             +[-<+]-  >>         Find 255 marker and go to the boolean
             [-]+                Set boolean to 1 whatever the previous value is
             ++++[---->++++]--   Find value 252 and change to 254
             >[->+<]             Reset the current FizzBuzz countdown
             >>[.>]              Print the text
             ++[-->++]           Go to next 254 change to 256 to break loop
         ]
     -->

     +++ Detect if we are at the 253 end
     ]
  ---

ALL FIZZBUZZES PROCESSED
Use the boolean to check whether or not to print the number


  +[-<+]-     Go back to the 255 marker
  >>          Go to boolean
  -[+         If boolean is zero then print the number

         Code taken from StackOverflow below for printing a number
>++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>>[-]>>>++++++++++<[->-[>+>>]>[+[-
<+>]>+>>]<<<<<]>[-]>>[>++++++[-<++++++++>]<.<<+>+>[-]]<[<[->-<]++++++[->++++++++
<]>.[-]]<<++++++[-<++++++++>]<.[-]<<[-<+>]
         End of StackOverflow code

         cursor is now located on the boolean
  ]

  Boolean is now zero so just print the new line
  <<<.      Print new line
  <         Go to the countdown to find out if we should go another round
]
ответил Simon Forsberg 7 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 07 Sep 2015 14:44:54 +0300 2015, 14:44:54
36
  • Вам следует «инициализировать 100» после «Значений ленты». Я считаю, что это часть фактического кода, а объяснение - своего рода «заголовок», объясняющий код.

  • Я согласен с тем, что комментировать «что» становится более важным в bf, но вы все равно должны объяснять «почему» время от времени. Причина, по которой вы строите строки «Fizz» и «Buzz», как вы делаете, не очевидна. Простой «Это более эффективно, чем прямое создание букв». комментарий проделан долгий путь. Также нет никаких указаний относительно того, почему вы оставляете два нуля в конце каждой строки.

  • Я не могу понять, что здесь делает эта метка. Это немного запутанно. Все, что в bf не является допустимым оператором, - это комментарий. Вы не используете хеши для комментариев в другом месте, не делайте этого и здесь.

+++ # Detect if we are at the 253 end

В целом это самый читаемый bf, на который я положил глаза. Однако не следует упускать из виду комментарий фактического кода как указание на то, что это было сделано правильно. Честно говоря, я понятия не имею. Я должен был бы разобраться с машинами Тьюринга и потратить некоторое время на то, чтобы написать что-то простое, чтобы понять правильное мышление, чтобы расшифровать это. Я в основном хотел опубликовать ответ, чтобы, возможно, он подтолкнул бы кого-то другого серьезно взглянуть на него.

ответил RubberDuck 1 stEurope/Moscowp30Europe/Moscow09bEurope/MoscowMon, 01 Sep 2014 23:30:10 +0400 2014, 23:30:10
0

Я нашел этот вызов довольно интересным для попадания в мозг. Я также сделал программу FizzBuzz.

++++++++[>+++++++++>+++++++++++++>++++++++>+++++++++++++++>+++++++++++++++>++++++++++++
+<<<<<<-]>-->+>++>--->++>---->>>+++>+++++<<<<[->+>>>>>+<<<-[<<->>[-<+>]]<<[-<<[<]>.>.>>
>..>>>+++>>>>[-]<<<<<]+>[->+<]>>-[[-<<+>>]<<<->>>]<<<[<<<<.>.>..>>->+++++>>>>[-]<<<<<]>
[->>+<<]>>>+>[-<[->+>>+<<<]>[-<+>]>>>+[[-]<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+
<[->[-]>>+>+<<<]]]]]]]]]<]>>[>]++++++[-<++++++++>]>>]<<<[.[-]<<<]]++++++++++.[-]<<<<<<]

, вероятно, может быть короче при использовании лучшего способа генерации символов ASCII или переупорядочения переменных для более коротких путей.

Это небольшое описание кода:

Tape: [ 0 "F" "i" "B" "u" "z" countdown(100) temp0 temp1 3counter 5counter cycleCount F/Bskipped temp3 numGen ]

70 F
105 i
66 B
117 u
122 z

++++++++[>+++++++++>+++++++++++++>++++++++>+++++++++++++++>+++++++++++++++>+++++++++++++<<<<<<-]
>--F>+i>++B>---u>++z>---- counter(100)
>>>+++>+++++ 3 and 5 counters
<<<<[ 100 times
  - decrement countdown
  >+ set temp0 = 1 (else flag)
  >>>>>+ set F/Bskipped flag
  <<<- decrement 3counter
  [  if not 0
    <<- delete else flag
    >>[-<+>] move 3count to temp1 (exit if)
  ]
  <<[ else (if 3counter = 0)
    - set temp0 = 0 (delete else flag)
    <<[<]>.>.>>>.. print Fizz
    >>>+++ set temp1 = 3
    >>>>[-] delete Fizz skipped flag
    <<<<< go back to temp0
  ]
  + set temp0 (else flag)
  >[->+<] move value back to 3counter
  >>- decrement 5counter
  [ if not 0
     [-<<+>>] move 5counter to temp1 (exit if)
     <<<- delete else flag
     >>> back to 5counter
  ]
  <<<[ else (if 5counter = 0)
    <<<<.>.>.. print Buzz
    >>- delete else flag (temp0)
    >+++++ set temp1 = 5
    >>>>[-] delete Buzz skipped flag
    <<<<< return to temp0
  ]
  >[->>+<<] move temp1 back to 5
  >>>+ increment cycleCount
  >[ if F/Bskipped flag is set (none of them were printed)
    - delete flag
    <[->+>>+<<<] copy cycleCount to flag and numGen
    >[-<+>] move value back from flag to count
    >> go to numGen
    >+[[-]<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->[-]>>+>+<<<]]]]]]]]]<]>>[>]++++++[-<++++++++>]>>]<<<[.[-]<<<]
    use "print value" routine from [https://esolangs.org/wiki/Brainfuck_algorithms#Print_value_of_cell_x_as_number_for_ANY_sized_cell_.28ie_8bit.2C_16bit.2C_etc.29]
    routine exits at F/Bskipped flag
  ]
  ++++++++++.[-] print lf
  <<<<<< go back to countdown
] 
ответил Dorian 3 J000000Tuesday18 2018, 11:47:53

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132