Коли цілі числа приєднуються до черги


26

Вступ

Черга є абстрактним типом даних , де елементи додаються до передніх (Enqueue) і віддалені від задньої (DEQUEUE). Це також відоме як принцип FIFO (First In First Out) .

Найкраще це показано на прикладі:

введіть тут опис зображення


Виклик

Враховуючи не порожній масив, який містить додатні цілі числа та елементи, які вказують на dequeue (видалення елемента), виведіть остаточний список черги.

Скажімо, що Xв даному прикладі позначається декупаж. Давайте подивимось на наступний список:

[45, X, X, 37, 20, X, 97, X, 85]

Це можна перекласти у наступний псевдо-код черги:

                   Queue
Enqueue 45    ->   45
Dequeue       ->   
Dequeue       ->              (dequeue on an empty queue is a no-op)
Enqueue 37    ->   37
Enqueue 20    ->   20 37
Dequeue       ->   20
Enqueue 97    ->   97 20
Dequeue       ->   97
Enqueue 85    ->   85 97

Ви можете побачити, що врешті-решт результат є [85, 97], який є результатом для цієї послідовності.


Тестові справи

Зауважте, що ви можете обрати будь-який інший символ або символ X, якщо це не додатне ціле число.

[1, X, 2, X, 3, X]      ->     []
[1, 2, X]               ->     [2]
[1, 2, 3]               ->     [3, 2, 1]
[1, 2, X, X, X, 3]      ->     [3]
[1, 2, X, 3, X, 4]      ->     [4, 3]

Це , тому подання з найменшою кількістю байтів виграє!


Чи може це бути пробіл, розділений пробілом, а не масив?
Райлі

@Riley Sure, що найкраще для тебе працює
Аднан

2
Чи можемо ми використовувати негативне число для x (Haskell не підтримує неоднорідні списки)
Загальне відображуване ім’я

2
... або інші невід'ємні цілі числа, такі як нуль або півтора?
Джонатан Аллан

@GenericDisplayName Хм, хороший момент. Я дозволю це, поки це не додатне ціле число
Аднан

Відповіді:


4

Желе , 8 байт

F;@Ṗṛ?¥/

Використовує будь-яке хибне значення ( 0 або порожнє ітерабельне) для відключення.

Спробуйте в Інтернеті!

Як це працює

F;@Ṗṛ?¥/  Main link. Argument: A (array)

       /  Reduce A by the link to the left.
      ¥     Combine the two links to the left into a dyadic chain.
F             Flatten the left argument.
    ṛ?        If the right argument is truthy:
 ;@             Concatenate the right argument and the flattened left argument.
              Else:
   Ṗ            Pop; remove the last element of the flattened left argument.
                This is why flattening is required, as Ṗ doesn't handle integers
                as intended for this challenge.

1
Насправді це не заборонено. Заборонено лише додатні цілі числа, 0 - нейтральні.
Ерік Аутгольфер

Це не те, що було сказано, коли я опублікував свою відповідь, але дякую за голову.
Денніс


7

Математика, 102 байти

Однозначно не найкоротше рішення, але я не втримався, тому що це збочення.

r=Reverse@{##}&
a_~f~b___:=b
f[a_,b___,]:=b
ToExpression[{"r[","f["~Table~StringCount[#,"]"],#}<>"]"]&

Після деяких допоміжних функцій це визначає чисту функцію, яка приймає рядок як вхідний: у рядку числа розділяються комами (пробіл не є обов'язковим); характер dequeue є "]"; і в списку немає роздільників спереду чи ззаду. Наприклад, перший приклад в ОП буде вводитись як рядок"45,],],37,20,],97,],85" . Виведенням функції є список чисел.

Функція підраховує кількість запитів "]"у вхідному рядку, додає стільки копій "f["на передню частину рядка, а потім оточує всю справу на "r[...]". У наведеному вище прикладі це дає результат"r[f[f[f[f[45,],],37,20,],97,],85]" ; зауважте, дужки врівноважені.

Потім ToExpressionінтерпретує отриманий рядок як фрагмент коду Mathematica і виконує його. Функція fзручно визначена для збереження всіх своїх аргументів, за винятком першого (а також ігнорує проміжні коми; це все одно необхідно обробляти видалення порожніх черг) і rперетворює отриману послідовність чисел у список чисел у потрібному порядку.


Чи кома в рядку 3 на b___,увазі повинна бути там? Це працює , але кома стає червоною через це. (також, яка різниця між рядками 2 та 3?)
numbermaniac

1
Добре око :) Рядок 2 еквівалентний f[a_,b___]:=b(без коми), а рядок 3 - рівносильному f[a_,b___,Null]:=b. В обох випадках b___посилається на будь-яку кількість аргументів (включаючи жодних). Рядок 3 є більш конкретним, тому завжди використовується перед рядком 2, коли це доречно. Таким чином, функція fігнорує свій перший аргумент, а також ігнорує останній аргумент, якщо такий аргумент є Null. Це було необхідно, щоб обробити видалення порожньої черги. Зауважте, що типовий вхід дасть вираз типу r[f[f[f[5,3,],2,],],11], де кожна кома перед цим ]знову позначає a Null.
Грег Мартін

1
Нічого собі, дуже приємно :). До речі, я думаю, що це насправді 102 байти; ви, можливо, порахували додатковий символ нового рядка наприкінці.
numbermaniac


4

JavaScript, 70 63 53 50 43 байт

Дякуємо @Neil за те, що ти граєш на 10 байт з x.map замість циклу та потрійного вираження

Дякуємо @Arnauld за те, що ти граєш на 3 байти

Дякуємо @ETHproductions за те, що грає в 7 байт

x=>(t=[],x.map(a=>+a?t=[a,...t]:t.pop()),t)

Спробуйте в Інтернеті!

Dequeue може бути будь-яким нечисловим значенням, крім істинного.


Це буде коротше, якщо ви використовуєте термінал замість if оператора, і ще коротше, якщо ви використовуєте mapзамість циклу, і ще коротше, якщо ви використовуєте вираз замість блоку. Дивіться поради .
Ніл

Я опублікував першу версію, яку я працював. Потім я з'їв вечерю: P
fəˈnɛtɪk

Ви можете зробити, x=>(t=[],x.map(a=>a>0?t.unshift(a):t.pop()),t)щоб зберегти небагато байтів наreturn
ETHproductions

x=>x.map(a=>a>0?t.unshift(a):t.pop(),t=[])&&tще коротше.
Ніл

(Або просто a?вистачає, гадаю?)
Ніл

3

Математика, 46 45 байт

Завдяки ngenisis за збереження 1 байта.

Reverse[#//.{_Integer:0,a___,X,b___}:>{a,b}]&

В основному такий же, як і моя відповідь Сітківки, використовуючи відповідність шаблонів. Ми неодноразово співпадаємо з першим Xі видаляємо його разом з першим номером (якщо такий існує). Після завершення ми перевернемо список.



3

Haskell, 41 байт

x&y:z|y<1=init x&z|w<-y:x=w&z
x&y=x
([]&)

Ninja'd :), схоже, у нас була одна і та ж ідея
Загальне відображуване ім’я

(Хоча вам потрібні дужки навколо y: z likex&(y:z)
Загальне відображуване ім’я

Це працює в моїй REPL, яка є частиною обіймів. Я не впевнений у точній версії.
Майкл Клейн

3

MATL , 13 12 байт

vi"@?@wh}IL)

Введення - це масив чисел, з 0"dequeue".

Вихід - це числа, розділені пробілами. Порожній результат відображається як нічого.

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

v        % Concatenate stack contents: gives []. This will grow to represent the queue
i        % Input numeric array
"        % For each entry in the input array
  @?     %   If current entry is non-zero
    @wh  %     Prepend current entry to the queue
  }      %   Else
    IL)  %     Remove last element from the queue
         %   End (implicit)
         % End (implicit)
         % Display (implicit)

3

Хаскелл, 41 40 байт

l#a|a>0=a:l|l>[]=init l|1>0=l

Функція foldl(#)[](Також включена в рахунок рахунку з байтом поділу між ними)

Спробуйте в Інтернеті!

X - будь-яке непозитивне ціле число

EDIT: -1 байт завдяки nimi


Ви можете перевернути останні два охоронці, щоб зберегти байт:|l>[]=init l|1>0=l
nimi

3

Джулія, 78 76 73 57 байт

f(a)=(q=[];[x<1?q=q[2:end]:push!(q,x)for x=a];reverse(q))

Дякуємо Гаррісону Гродіну за чудові пропозиції щодо гольфу в Джулії. Замінено if / else на потрійний та для / end з розумінням списку для економії 16 байт.

f(a)=(q=[];for x in a if x<1 q=q[2:end]else q=[q...,x]end end;reverse(q))

Вилучено кілька зайвих пробілів, щоб заощадити 3 байти.

Перш ніж дозволено негативне число чи нуль:

f(a)=(q=[];for x in a if x==:X q=q[2:end] else q=[q...,x] end end;r everse(q))

Безголівки:

function dequeue(list)
    queue = []

    for x in list
        if x < 1
            queue = queue[2:end]
        else
            queue = [queue..., x]
        end
    end

    reverse(queue)
end

Я досить новачок у Юлії; може бути кращий спосіб. Використовує :Xдля X, що є символом у Джулії. Оновлено: тепер, коли дозволено 0, використовує 0 (або будь-яке від’ємне число) для X, зберігаючи два символи. Знову оновлено, щоб видалити пробіл, який я не розумів, що не потрібен.


2

05AB1E , 12 11 байт

Збережено байт завдяки Райлі

)Evyai¨ëy¸ì

Спробуйте в Інтернеті!

Пояснення

Записи позначаються будь-якою буквою .

)             # wrap stack in a list (pushes empty list)
 Ev           # for each y in evaluated input
   yai        # if y is a letter
      ¨       # remove the first element of the list
       ëy¸ì   # else, prepend y to the list

2

GNU Sed, 43

Оцінка включає +2 для використання -r та -nпрапорів.

G
s/X\n( *|(.*)\b\S+ *)$/\2/
s/\n/ /
h
$p

Спробуйте в Інтернеті .

Пояснення

                            # Implicitly read the next line
G                           # append a newline, then the contents of the hold space
s/X\n( *|(.*)\b\S+ *)$/\2/  # If the input was an X, remove it, the newline, and any element at the end
s/\n/ /                     # Otherwise if the input was not an X, it is simply enqueued by removing the newline between it and the rest of the line
h                           # save a copy of the queue to the hold space
$p                          # since we're using -n to suppress output at the end of processing each input line, then this explicit print is required in the last line

2

PHP, 85 байт

<?$r=[];foreach($_GET as$v)is_int($v)?array_unshift($r,$v):array_pop($r);print_r($r);

-8 байт $vзамість того, is_int($v)якщо кожне значення dequeue належить false



2

Perl 5 , 28 + 1 = 29 байт

28 байт коду + -pпрапор.

/\d/?$\=$_.$\:$\=~s/.*
$//}{

Спробуйте в Інтернеті!

Він використовує рядок ( $\) в якості черги: коли вхід містить ціле число ( /\d/?, ми додаємо його на початку $\( $\=$_.$\), а в іншому випадку видаляємо останнє з s/.*\n$//. В кінці, $\неявно друкується завдяки -pпрапору (і ті, що не мають собі рівних }{).


Інші підходи:

  • 33 байти , використовуючи масив в якості черги (я вважаю, це найбільш природний спосіб зробити це в Perl, я думаю, але не найкоротший):

    /X/?pop@F:unshift@F,$_}{$_="@F"

    Спробуйте в Інтернеті!

  • 52 байти , використовуючи регулярний вираз і reverse(трапляється, це абсолютно те саме, що відповідь Ретіна Мартіна Ендера - завдяки якому я зберег на ньому 2 байти). Зворотний перелік списку займає багато символів, оскільки для збереження цілих чисел я повинен перетворити рядок у масив, щоб повернути його назад, а потім назад у рядок для його друку. ( say forзамість цього $_=join$",можна зберегти 2 байти, але це вимагає -Eабо -M5.010це не так цікаво).

    s/\d+ (.*?)X ?|^X/$1/&&redo;$_=join$",reverse split

    Спробуйте в Інтернеті!



1

Пакетна, 160 байт

@set s=.
@for %%n in (%*)do @if %%n==X (call set s=%%s:* =%%)else call set s=%%s:~,-1%%%%n .
@set t=
@for %%n in (%s:~,-1%)do @call set t= %%n%%t%%
@echo%t%

Це було складніше, ніж треба було.

  • Хоча Batch може перерахувати результат розщеплення рядка, він не може легко видалити елемент з перерахунку.
  • Він може видалити перший елемент, але лише за наявності хоча б одного елемента. Інакше ви отримуєте сміття.

Це означає, що мені а) потрібно мати маркер кінця черги, який не видаляється, і б) маніпулювати чергою вперед, тому нові елементи вставлятимуться безпосередньо перед кінцевим маркером, щоб старі елементи можна було видалити спереду, а це означає, що я в) повинен повернути чергу перед друком.



1

C #, 115 байт +33 байти для використання

l=>{var r=new List<int>();foreach(var n in l)if(n<0)try{r.RemoveAt(0);}catch{}else r.Add(n);r.Reverse();return r;};

Анонімний метод, який повертає список цілих чисел після виконання операцій додавання в чергу та відключення. Негативні цілі числа використовуються для видалення елементів з черги.

Повна програма з методом unolfolf та тестовими кейсами:

using System;
using System.Collections.Generic;

public class Program
{
    static void PrintList(List<int> list)
    {
        var s = "{";
        foreach (int element in list)
            s += element + ", ";
        if (s.Length > 1)
            s += "\b\b";
        s += "}";
        Console.WriteLine(s);
    }

    public static void Main()
    {
        Func<List<int>, List<int>> f =
        l =>
        {
            var r = new List<int>();
            foreach (var n in l)
                if (n < 0)
                    try
                    {
                        r.RemoveAt(0);
                    }
                    catch
                    { }
                else
                    r.Add(n);
            r.Reverse();
            return r;
        };

        // test cases:
        var list = new List<int>(new[]{1, -1, 2, -1, 3, -1});   // {}
        PrintList(f(list));

        list = new List<int>(new[]{1, 2, -1});  // {2}
        PrintList(f(list));

        list = new List<int>(new[]{1, 2, 3});   // {3, 2, 1}
        PrintList(f(list));

        list = new List<int>(new[]{1, 2, -1, -1, -1, 3});   // {3}
        PrintList(f(list));

        list = new List<int>(new[]{1, 2, -1, 3, -1, 4});    // {4, 3}
        PrintList(f(list));
    }
}

1

Скала, 97 байт

type S=Seq[_];def f(a:S,b:S):S=a match{case h::t=>f(t,if(h==0)b dropRight 1 else h+:b);case _=>b}

В якості введення fприймає список з 0елементом "dequeue". Він використовує хвостову рекурсію з другим параметром ( b), виконуючи роль акумулятора. Спочатку bце порожній Seq( Nil).

Пояснення:

type S=Seq[_]                               // defines a type alias (save 1 byte since Seq[_] is used 3 times)
def f(a: S, b: S): S = {                    // a is the initial list, b is an accumulator
    a match {                           
        case h::t =>                        // if a is non-empty
            f(t,                            // recursive call to f with 1st parameter as the tail
                if (h==0) b dropRight 1     // if h == 0 (dequeue) then remove last element of b,
                else h+:b                   // otherwise, just add h at the beginning of b in recursive call
            )
        case _ => b                         // when the list is empty, return b (final result)
    }
}

Примітка: b dropRight 1 використовується замість , b.tailщоб уникнути виключення: tail of empty list.

Тестові приклади:

f(Seq(45, 0, 0, 37, 20, 0, 97, 0, 85), Nil)     // List(85, 97)
f(Seq(1, 0, 2, 0, 3, 0), Nil)                   // List()
f(Seq(1, 2, 0), Nil)                            // List(2)
f(Seq(1, 2, 3), Nil)                            // List(3, 2, 1)
f(Seq(1, 2, 0, 0, 0, 3), Nil)                   // List(3)
f(Seq(1, 2, 0, 3, 0, 4), Nil)                   // List(4, 3)

fможе також працювати з іншими типами ( String, char..., навіть гетерогенний список цих типів!):

f(Seq(false, '!', "world", 0, "Hello"), Nil)    // List(Hello, world, !)

1

REXX, 115 байт

arg n
do while n>''
  parse var n m n
  if m=X then pull
  else queue m
  end
o=
do while queued()>0
  pull a
  o=a o
  end
say o

Займає розділений пробілом рядок, друкує рядок, розділений пробілом



1

Швидкий 3, 70 байт

Якщо припустити, що у нас є масив типу Ints let x = [1, 2,-1,3,-1,4]

print(x.reduce([].prefix(0)){(a,i)in return i>0 ?[i]+a:a.dropLast(1)})

Зауважте, що [].prefix(0)це підлий спосіб отримати порожній ArraySlice

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.