Управління чергою чорної п’ятниці


10

Вступ

Ви керуєте відділом електроніки у великому магазині роздрібної торгівлі, і найбільший день продажу в цьому році - це п’ятниця . Щоб допомогти управляти натовпам, ваш магазин впроваджує систему квитків на найбільші угоди, де клієнти повинні пред’явити квиток перед покупкою товару. Ваше завдання - написати програму для підтвердження квитків.

Оскільки єдиний доступний комп’ютер у магазині (через скорочення бюджету) - це динозавр зі зламаною клавіатурою, (і все, що у вас є, це клавіатури USB, які не сумісні), вам доведеться вводити програму мишкою. Тому ваша програма повинна бути якомога коротшою.

Продукція

У вашому магазині продаються п'ять різних продуктів, перелічених нижче. Кожен товар має загальну малу назву та різні правила щодо того, скільки можна придбати та в який час доби.

  • television: Є в наявності 5телевізори з плоским екраном, які можна придбати з 00:00:00(опівночі) до 00:59:59.
  • smartphone: На складі є 10смартфони, однак будь-який клієнт, що перебуває з 00:00:00(опівночі), 00:59:59отримує ваучер на один раз, коли він закінчується.
  • tablet: Є 10планшети, які можна придбати в будь-який час.
  • laptop: Існує необмежена кількість ноутбуків, які можна придбати з 00:00:00(опівночі) до 07:59:59.
  • lightbulb: Є необмежена кількість лампочок, які можна придбати в будь-який час.

Вхідні дані

Багаторядковий рядок з кожним рядком у наступному форматі. Рядки сортуються за позначкою часу.

<time stamp> <product name> <ticket number>
  • Номер квитка - 8 цифр. Остання цифра - це контрольна цифра, що дорівнює сумі перших семизначних модуля 10. Щоб бути дійсним, номер квитка повинен мати правильну контрольну цифру і повинен бути строго більшим за всі попередні номери квитків.
  • Назва продукту - одна з перелічених вище рядків.
  • Марка часу - це час доби у форматі, HH:MM:SSде HHє двоцифрова година з 00-23, MMі SSє двоцифровою хвилиною та секундою відповідно.

Вихідні дані

Вихід є одним з наступних рядків, з одним рядком на квиток. Умови повинні застосовуватися для того, щоб .

  1. Expired offer (Застосовується до телевізорів, смартфонів та ноутбуків.) Позначення часу на квитку відбувається після закінчення купівлі товару.
  2. Invalid ticket Або номер квитка менший або рівний номеру попереднього квитка, або контрольна цифра недійсна.
  3. Give voucher (Застосовується до смартфонів.) Товар відсутній на складі, але всі клієнти в черзі до закінчення терміну дії пропозиції отримують дощову перевірку.
  4. Out of stock(Застосовується до телевізорів та планшетів.) Весь товар проданий. Вибачте, кількість була обмежена.
  5. AcceptedВсі умови дотримані, тому дайте їм товар. Зауважте, що лише прийняті квитки зменшують кількість товарів на складі.

Приклад

Input                           Output
----------------------------    --------------
00:00:00 television 00010001    Accepted
00:00:25 smartphone 00011697    Accepted
00:01:25 laptop 00030238        Accepted
00:02:11 smartphone 00037291    Accepted
00:02:37 lightbulb 00073469     Invalid ticket
00:03:54 smartphone 00096319    Accepted
00:05:26 tablet 00152514        Accepted
00:06:21 tablet 00169893        Accepted
00:07:10 television 00190268    Accepted
00:07:47 smartphone 00194486    Accepted
00:07:55 tablet 00220071        Accepted
00:08:20 lightbulb 00321332     Accepted
00:10:01 smartphone 00409867    Accepted
00:11:10 tablet 00394210        Invalid ticket
00:11:46 television 00581060    Accepted
00:12:44 lightbulb 00606327     Accepted
00:13:16 tablet 00709253        Accepted
00:13:53 television 00801874    Accepted
00:14:47 laptop 00832058        Accepted
00:15:34 smartphone 00963682    Accepted
00:16:24 smartphone 01050275    Accepted
00:17:45 tablet 01117167        Accepted
00:18:05 laptop 01107548        Invalid ticket
00:19:00 lightbulb 01107605     Invalid ticket
00:19:47 lightbulb 01492983     Accepted
00:19:50 smartphone 01561609    Accepted
00:21:09 television 01567098    Accepted
00:21:42 laptop 01597046        Accepted
00:22:17 smartphone 01666313    Accepted
00:24:12 tablet 01924859        Accepted
00:24:12 smartphone 02151571    Accepted
00:25:38 smartphone 02428286    Give voucher
00:31:58 television 02435284    Out of stock
00:35:25 television 02435295    Out of stock
00:52:43 laptop 02657911        Invalid ticket
00:53:55 smartphone 02695990    Give voucher
01:08:19 tablet 02767103        Accepted
01:34:03 television 02834850    Expired offer
01:56:46 laptop 02896263        Accepted
02:02:41 smartphone 03028788    Expired offer
02:30:59 television 03142550    Expired offer
02:51:23 tablet 03428805        Accepted
03:14:57 smartphone 03602315    Expired offer
03:27:12 television 03739585    Expired offer
03:56:52 smartphone 03997615    Expired offer
04:07:52 tablet 04149301        Accepted
04:12:05 lightbulb 04300460     Invalid ticket
04:24:21 laptop 04389172        Accepted
04:40:23 lightbulb 04814175     Accepted
04:40:55 tablet 04817853        Accepted
04:42:18 smartphone 04927332    Expired offer
05:06:43 tablet 05079393        Out of stock
05:16:48 tablet 05513150        Out of stock
05:33:02 television 05760312    Expired offer
05:43:32 tablet 06037905        Out of stock
06:12:48 smartphone 06440172    Expired offer
06:35:25 laptop 06507277        Accepted
06:42:29 lightbulb 06586255     Invalid ticket
06:55:31 lightbulb 06905583     Accepted
06:55:33 lightbulb 06905583     Invalid ticket
07:40:05 smartphone 07428006    Expired offer
07:49:12 television 07588086    Expired offer
08:14:56 laptop 08111865        Expired offer

Я намагався зробити приклад, який охоплює всі можливі сценарії виводу, але, будь-ласка, залиште коментар, якщо щось незрозуміле.

Це , ви можете написати програму або функцію, а стандартні отвори в петлі заборонені.

Відповіді:


5

Javascript (ES6), 396 433 419 байт

h=0;f=1/0;i={television:{c:5,s:0,e:1},smartphone:{c:10,s:0,e:1,v:1},tablet:{c:10,s:0,e:24},laptop:{c:f,s:0,e:8},lightbulb:{c:f,s:0,e:24}};while(1){t=prompt().split(' ');a=t[0];r=a[0]+a[1]-0;o=i[t[1]];m=0;z='Accepted';u=t[2]-0;u<=h||(u-u%10+'').split('').reduce((p,c)=>-(-p-c))%10!=u%10?m='Invalid ticket':0;r<o.s||r>=o.e?m='Expired offer':0;if(!m)o.c?o.c--:(o.v?z='Give voucher':m='Out of stock');!m?h=u:0;alert(m?m:z)}

Правка: зменшений розмір за допомогою функції великої стрілки es6

Більш зрозумілі:

h=0
f=1/0
i={television:{c:5,s:0,e:1},smartphone:{c:10,s:0,e:1,v:1},tablet:{c:10,s:0,e:24},laptop:{c:f,s:0,e:8},lightbulb:{c:f,s:0,e:24}}
while(1){t=prompt().split(' ')
a=t[0]
r=a[0]+a[1]-0
o=i[t[1]]
m=0
z='Accepted'
u=t[2]
if(u<=h||(u-u%10+'').split('').reduce(function(p,c){return-(-p-c)})%10!=u%10)m='Invalid ticket'
if(r<o.s||r>=o.e)m='Expired offer'
if(!m){if(o.c)o.c--
else o.v?z='Give voucher':m='Out of stock'}if(!m)h=u
alert(m?m:z)}

Цікаво, що довший код швидше: http://jsperf.com/compare-read

GUI з такою ж логікою:

var app = angular.module('app', []);

app.controller('MainCtrl', function MainCtrl ($scope) {
  $scope.items = {
    television: {c: 5, s:0, e: 1},
    smartphone: {c: 10, s:0, e: 1},
    tablet: {c:10, s:0, e: 24},
    laptop: {c:Infinity, s: 0, e: 8},
    lightbulb: {c: Infinity, s: 0, e: 24},
  };
  
  var h = -1;//highest
  
  $scope.hours_offset = 0;
  
  $scope.ticket = {};
  for (var i = 0; i < 8; i++) $scope.ticket[i] = 0;
  
  $scope.selected_item = -1;
  
  $scope.nums = new Array(10);
  
  $scope.history = [];
  
  $scope.buy = function() {
    
  }
  $scope.selectItem = function($i) {
    $scope.selected_item = $i;
  }
  
  $scope.purchase = function() {
    if ($scope.selected_item === -1)
      return;

    var ticnum = '';
    var msg = 'Accepted';
    
    for(var key in $scope.ticket)
      ticnum+=$scope.ticket[key];
    
    var d = new Date();
    
    //Variable declarations to setup for code like the code I designed for console
    r = d.getHours()-$scope.hours_offset;//hour
    o = $scope.items[$scope.selected_item];//item
    m = 0//msg
    z = 'Accepted'//default_msg
    u=ticnum
    
    //This is copied from my console code
    if(ticnum<=h||(ticnum-ticnum%10+'').split('').reduce(function(p,c){return-(-p-c)})%10!=ticnum%10)m='Invalid ticket'
	if(r<o.s||r>=o.e)m='Expired offer'
	if(!m){if(o.c)o.c--
	else o.v?z='Give voucher':m='Out of stock'}if(!m)h=ticnum
	
    msg = m?m:z;
    
    $scope.history.unshift({
      time: time(d),
      item: $scope.selected_item,
      ticket_num: ticnum,
      message: msg
    });
    
  }
});

function time(date) {
  return padToTwo(date.getHours()) + ':' + padToTwo(date.getMinutes()) + ':' + padToTwo(date.getSeconds());
}
    
function padToTwo(number) {
  return number = ("00"+number).slice(-2);
}
#parent {
  width: 100vw;
  height: 100vh;
  
  padding-bottom: 25vh;
}
#parent > div {
  padding-top: 25vh;
  
  -webkit-display: flex;
  display: flex;
  
  -webkit-flex-direction: row;
  flex-direction: row;
  
  -webkit-align-items: flex-start;
  align-items: flex-start;
  -webkit-justify-content: center;
  justify-content: center;
}

#items {
  width: 15vw;
  min-width: 110px;
  margin-right: 4vw;
  background-color: #222223;
  color: #eeeeef;
  border-radius: 4px;
  border: 2px solid black;
}

#items > span {
  box-sizing: border-box;
  display: block;
  padding: 5px;
  
  -webkit-transition: .2s background-color ease-in-out;
  transition: .2s background-color ease-in-out;
  
  text-align: center;
  
  width: 100%;
  
  border-radius: 4px;
}
#items > span:hover, #ticket p:hover {
  background-color: gray;
}
#items > span.selected, #ticket p.selected {
  background-color: #999999;
}
#ticket {
  -webkit-display: flex;
  display: flex;
  
  -webkit-flex-direction: row;
  flex-direction: row;
  
  margin-right: 4vw;
  
  color: #eeeeef;
}

#ticket p {
  margin: 1px;
  padding: 3px;
  width: 20px;
  text-align: center;
  background-color: #22222f;
  border: 2px solid black;
  border-radius: 3px;
}

#purchase {
  padding: 15px;
  padding-top: 6px;
  padding-bottom: 6px;
  
  background-color: #22222f;
  border: 2px solid black;
  border-radius: 3px;
  color: #eeeeef;
}
#purchase:active {
  background-color: gray;
}

#error {
  margin-top: 15px;
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<div id="parent" ng-app="app" ng-controller="MainCtrl">
  For testing hours-offset (If it's 6:00 setting this to 18 would simulate it being midnight): <input ng-model="hours_offset" type="number"></input>
  <div>
    <div id="items">
      <span ng-attr-class="{{selected_item===name ? 'selected' : ''}}" ng-repeat="(name, obj) in ::items track by $index" ng-click="selectItem(name)">{{::name}}<br></span>
    </div>
    <div id="ticket">
      <span ng-repeat="(ticket_index, val) in ::ticket">
        <p ng-attr-class="{{ticket[ticket_index]===$index ? 'selected' : ''}}" ng-repeat="nothing in ::nums track by $index" ng-click="ticket[ticket_index] = $index">{{::$index}}</p>
      </span>
    </div>
    <span id="purchase" ng-click="purchase()">Purchase</span>
  </div>
  <div id="error">{{error_msg}}</div>
  <table id="output">
    <tr ng-repeat="item in history track by $index">
      <td ng-repeat="(key, value) in item track by $index">{{value}}</td>
    </tr>
  </span>
</div>


Ласкаво просимо до PPCG. Хоча ваш GUI - це щось, об'єктом коду гольфу є написання найкоротшої програми. Оскільки ви використовуєте JavaScript, ви можете взяти рядок введення як функціональний параметр і повернути результат. Також слід видалити зайвий пробіл і скоротити імена змінних. Чому б вам не переглянути деякі інші питання, щоб зрозуміти, як працює сайт?
intrepidcoder

@intrepidcoder Звичайно, ви б потім зменшили код! Але виходячи зі сценарію, мені здається, що консоль була б неефективною без клавіатури!
csga5000

1
Відповідно до правил, викладених у нашому довідковому центрі , ця публікація є поза темою у своєму поточному стані. Усі рішення викликів повинні: [...] бути серйозним претендентом на виграшні критерії, які використовуються. Наприклад, для участі в змаганні з кодом з гольфу потрібно пройти гольф [.]
Денніс

Це було абсурдно раціональним для короткої довжини коду і не мало нічого спільного з реальною проблемою. Сукупний розмір ваших трьох програм - 4,51 Кб. Якщо ви не намагаєтесь зменшити його, повідомлення, ймовірно, буде видалено.
intrepidcoder

@intrepidcoder О так! Я забув про це, було дуже багато обмежень xD. Коли ви говорите останню цифру, ви маєте на увазі MSB або LSB? Я здогадуюсь про LSB, але хочу бути впевненим.
csga5000
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.