Гольф в банке


11

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

База данных

К счастью, наша база данных очень проста (она была создана школьным сыном президента нашего банка), и у нас пока всего несколько клиентов.

файл Bank.data:

Account Firstname Lastname Balance Date
123 Maree Jones 346.22 2014-12-13
035 Thomas Breakbone 3422.02 2015-01-03
422 Henrietta Throsby-Borashenko 277847.74 2014-11-21
501 Timmy Bongo 7.95 2014-11-04
105 William Greene 893.00 2015-01-06
300 Mary Galoway 1228.73 2014-12-28
203 Samantha Richardson 2055.44 2014-11-01
151 Bruce Wayne 956119.66 2014-10-09
166 Chip Stonesmith 266.71 2014-12-15
888 Alexandria Cooper 1299.82 2014-12-30

Спецификация приложения

Наше банковское приложение должно реализовывать следующие команды:

open <firstname> <lastname> Создает (открывает) новую учетную запись, печатая уникальный трехзначный номер учетной записи.

withdraw <account> <amount> Снять сумму со счета.

deposit <account> <amount> Внесите сумму на счет.

close <account> Закрыть счет, если он пуст.

report <fieldname> Распечатать отчет по базе данных, отсортированной по имени поля. Переместите столбец с именем поля на первую позицию. Ширина каждого столбца будет максимальной шириной данных и ширины имени поля, разделенных одним пробелом. Первая строка будет заголовками полей. Только весы должны быть правильно выровнены с ведущим $знаком.

print <account> Напечатайте имена полей и записи для этой учетной записи, отформатированные как отчет.

Каждый раз, когда запись изменяется, Dateполе в записи должно обновляться до текущей даты.

Приложение покажет приглашение «#» при ожидании команды. Если команда не выполняется (например, операция на неизвестном счете или недостаточно средств), приложение должно распечатать информационное сообщение об ошибке «ошибка». Программа должна записывать изменения обратно в файл после каждого изменения и читать из файла каждой команды, так как в мире существует много программ кассира, работающих с файлом одновременно (нам не нужна блокировка файла - это может снизить производительность).

РЕДАКТИРОВАТЬ: строковые поля являются простыми ASCII (az, AZ, -) без пробелов, и сумма всегда будет между 0,00 и 1000000000.00 (1 миллиард) долларов с 2 десятичными знаками, указывающими центы. Дата будет по местному времени в каждой ветви (простое решение, но может привести к некоторым проблемам позже ...).

Выход

Ответы должны будут продемонстрировать, что они соответствуют спецификации. Пожалуйста, приложите вывод из вашей программы после обработки следующих команд:

report Balance
open Clark Kent
print 001
deposit 001 4530
withdraw 105 893
close 105
report Date

Убедитесь, что вы используете оригинальную копию Bank.dataфайла, указанного выше.

счет

Это код-гольф, поэтому ваш счет будет количеством байтов вашего кода. Стандартные лазейки запрещены.


Должен ли быть способ выхода из программы?
bacchusbeale

Мы не хотим упаковывать слишком много функций в это приложение ;-) Выход типа control-C - это нормально.
Логика Найт

Какие ограничения могут быть приняты на символы в <firstname>и <lastname>и диапазон и точность <amount>? (Например, могут быть некоторые оптимизации, которые возможны, если <amount>всегда имеет ровно два десятичных знака - или вы можете захотеть, чтобы программа использовалась ближневосточной ветвью, где большинство валют используют три десятичных знака).
Питер Тейлор

Спасибо, Питер. Я добавил несколько предложений по типу строки и диапазону количества, как предложено.
Логика Найт

Возможно, я должен был быть более ясным в своем вопросе об именах. Самое полезное ограничение было бы , что <firstname>и <lastname>как только использовать a-zA-Z, но даже простое утверждение , что они никогда не содержат символы табуляции позволяет использовать TSV. Если они могут быть любой последовательностью символов ASCII, необходима некоторая форма экранирования или разделения, отличная от разделителя из одного символа.
Питер Тейлор

Ответы:


1

Руби, 918

Этот вопрос довольно длинный для гольфа, так как состоит из множества мелких деталей. На мгновение я почти хотел определить некоторые дополнительные классы, чтобы сделать вещи лучше с полиморфизмом и т. Д. (Но в конце концов я этого не сделал).

l=->a,i{a.map{|x|x[i].to_s.size}.max}
y=1..-1
d=File.open(f="bank.data").each.map(&:split)
j=[k=%w{Account Firstname Lastname Balance Date}]
_=->{puts"Failure"}
q=->t,v=0{z=-1;puts t.map{|r|([v]+((0..4).to_a-[v])).map{|c|b=l[t,c];c!=3?r[c].ljust(b):(?$*(z+=z<1?1:0)+r[c]).rjust(b>7?b+1:b)}*' '}}
w=->d{File.open(f,?w).write(d.map{|x|x*' '}*?\n)}
s=->i,m=!0{o=d.select{|r|r[0]==i};o==[]?_[]:m ?q[[k]+o]:1}
u=->{Time.now.to_s[0..9]}
($><<"# ";i=gets.split;o=i.size;("report"==h=i[0])?((v=k.index i[1])?q[j+d[y].sort_by{|x|v!=3?x[v]:x[v].to_f},v]:_[]):h=="print"?s[i[1],0]:h=="close"?(s[m=i[1]]?w[d=j+d[y].select{|r|r[0]!=m}]:0):h=="open"?((o==3&&t=((1..999).map{|x|'%03d'%x}-d.map{|x|x[0]})[0])?(w[d=d+[[t,i[1],i[2],'0.00',u[]]]];puts t):_[]):h=="withdraw"||h=="deposit"?(o==3&&s[i[1]]?w[d=j+d[y].map{|r|i[1]==r[0]?(b=(c=r[3].to_f)+i[2].to_f*(i[0][0]==?w?-1:1);0>b&&(b=c;_[]);r[0..2]+["%.2f"%b,u[]]):r}]:_[]):_[])while 1

Вероятно, можно играть в гольф дальше. Но на данный момент я даже не могу отслеживать, что я делал в последней строке.

Выход:

# report Balance
   Balance Account Firstname  Lastname           Date      
     $7.95 501     Timmy      Bongo              2014-11-04
   $266.71 166     Chip       Stonesmith         2014-12-15
   $346.22 123     Maree      Jones              2014-12-13
   $893.00 105     William    Greene             2015-01-06
  $1228.73 300     Mary       Galoway            2014-12-28
  $1299.82 888     Alexandria Cooper             2014-12-30
  $2055.44 203     Samantha   Richardson         2014-11-01
  $3422.02 035     Thomas     Breakbone          2015-01-03
$277847.74 422     Henrietta  Throsby-Borashenko 2014-11-21
$956119.66 151     Bruce      Wayne              2014-10-09
# open Clark Kent
001
# print 001
Account Firstname Lastname Balance Date      
001     Clark     Kent       $0.00 2015-02-01
# deposit 001 4530
# withdraw 105 893
# close 105
# report Date
Date       Account Firstname  Lastname              Balance
2014-10-09 151     Bruce      Wayne              $956119.66
2014-11-01 203     Samantha   Richardson           $2055.44
2014-11-04 501     Timmy      Bongo                   $7.95
2014-11-21 422     Henrietta  Throsby-Borashenko $277847.74
2014-12-13 123     Maree      Jones                 $346.22
2014-12-15 166     Chip       Stonesmith            $266.71
2014-12-28 300     Mary       Galoway              $1228.73
2014-12-30 888     Alexandria Cooper               $1299.82
2015-01-03 035     Thomas     Breakbone            $3422.02
2015-02-01 001     Clark      Kent                 $4530.00
#

Было бы очень полезно, если бы вы могли добавить пример выходных данных программы (см. Обновленный вопрос). Спасибо.
Логика Найт

Я знаю, что это побочный продукт неправильной подсветки синтаксиса, но суммы в долларах выглядят так круто, когда целые числа чёрным, а центы бледно-красным.
Джо З.

2

T-SQL 1919

Вызывается с "exec q 'Ваша команда здесь" "Я не думаю, что T-SQL может на самом деле получить пользовательский ввод, поэтому я думаю, что это настолько близко, насколько это возможно.

Использует утилиту bcp для ввода-вывода, которую я раньше не пробовал, поскольку она поставляется с SQL Server 2014.

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

CREATE PROC q @ CHAR(99)AS
CREATE TABLE ##(A CHAR(3),F CHAR(99),L CHAR(99),B MONEY,D DATE)bcp ## in Bank.data -t " " -T
DECLARE @g INT,@w MONEY,@z CHAR(9),@y CHAR(99),@x CHAR(99)SET @g=patindex('% %',@)SET @z=substring(@,1,@g-1)SET @=substring(@,@g+1,99)SET @g=patindex('% %',@)SET @y=substring(@,1,@g-1)SET @=substring(@,@g+1,99)SET @g=patindex('% %',@)SET @x=substring(@,1,@g-1)SET @w=CONVERT(MONEY,@x)*2*(LEN(@z)-7.5)IF @z='open'exec o @y,@x
IF @z='close'exec c @y
IF @z='withdraw'exec w @y,@w
IF @z='deposit'exec w @y,@w
IF @z='print'exec p @y
IF @z='report'exec r @y
bcp ## out Bank.data -t " " -T
SELECT'#'
CREATE PROC r @q CHAR(9)AS
DECLARE @a char(9)='A Account',@f char(11)='F Firstname',@l char(10)='L Lastname',@b char(45)='CONCAT(''$'',SPACE(9-LEN(B)),B) Balance',@d char(6)='D Date',@ varchar(999)='SELECT '
IF @q='Account'SET @+=@a+','+@f+','+@l+','+@b+','+@d
IF @q='Balance'SET @+=@b+','+@a+','+@f+','+@l+','+@d
IF @q='Date'SET @+=@d+','+@a+','+@f+','+@l+','+@b
IF @q='Lastname'SET @+=@l+','+@a+','+@f+','+@b+','+@d
IF @q='Firstname'SET @+=@f+','+@a+','+@l+','+@b+','+@d
IF LEN(@)<9
BEGIN
SELECT'failed'RETURN
END
SET @+=' FROM ## ORDER BY '+@q
exec(@)CREATE PROC p @ CHAR(3)AS
DECLARE @r CHAR(9)=(SELECT 1 FROM ## WHERE A=@)IF @r IS NULL SELECT'failed'ELSE SELECT*FROM ## WHERE A=@
CREATE Proc o @f CHAR(99),@l CHAR(99)AS
DECLARE @ INT=0,@r CHAR(9)=(SELECT 1 FROM # WHERE A='000')WHILE @r IS NOT NULL
BEGIN

SET @+=1
SET @r=(SELECT 1 FROM # WHERE CONVERT(INT,A)=@)END
IF @>999 SELECT'failed'ELSE INSERT INTO # OUTPUT Inserted.A VALUES(REPLICATE('0',3-LEN(@))+CONVERT(CHAR(3),@),@f,@l,0,GETDATE())CREATE PROC w @ CHAR(3),@b MONEY AS
DECLARE @r CHAR(9)=(SELECT 1 FROM ## WHERE A=@ AND B>@b)IF @r IS NULL SELECT'failed'ELSE UPDATE ## SET B=B-@b,D=GETDATE()WHERE A=@
CREATE Proc c @q CHAR(3)AS
DECLARE @r CHAR(9)=(SELECT 1 FROM ## WHERE A=@q AND B=0)IF @r IS NULL SELECT'failed'ELSE DELETE FROM ## WHERE A=@q

Было бы очень полезно, если бы вы могли добавить пример выходных данных программы (см. Обновленный вопрос). Спасибо.
Логика Найт

2

Кобра - 1505

class P
    var m='Account Firstname Lastname Balance Date'
    def main
        while[d=DateTime.now.toString('yyyy-MM-dd'),z='0.00']
            print'#'stop
            try,branch (c=Console.readLine.split)[r=0]
                on'open'
                    post while u in for x in.f get x[0],u=(r+=1).toString('000')
                    print u
                    .f=.f.toList+[@[u,c[1],c[2],z,d]]
                on'deposit'or 'withdraw'
                    n=.z(if(c[0]>'deposit','-','')+c[2])
                    assert.z(.i(c[1])[3])+n>=0
                    .f=for x in.f get if(x[0]==c[1],@[x[:3].join(' '),'[(.z(x[3])+n).toString(z)]',d],x)
                on'close'
                    assert.i(c[1])[3]==z
                    .f=for x in.f where.i(c[1])<>x
                on'report',.a(.f,c[1])
                on'print',.a([.i(c[1])])
                else,assert 0
            catch
                print'failed'
    def z(s='')as float
        return float.parse(s)
    pro f as String[]?*
        get
            return for x in File.readAllLines('Bank.data')[1:]get x.split
        set
            File.writeAllLines('Bank.data',[.m]+for x in value get x.join(' '))
    def a(f as String[]?*,c='Account')
        i,l=(m=.m.split).toList.indexOf(c),[7,9,8,8,4]
        assert c in m
        print (for q in (for z in (for x in[m]+f.toList.sorted(do(a as String[],b as String[]))get for y in 5 get[t=try' '.repeat(l[y]-x[y].length)catch get'',if(y-3,x[y]+t,t+if(x==m,' ','$')+x[y])][1])get[z[i]]+for p in z where p<>z[i])get q.join(' ')).join('\n')
            for v in[a,b],for k in 5,if (u=v[k].length)>l[k],l[k]=u
            return[d=a[i].compareTo(b[i]),d,d,.z(a[3]).compareTo(.z(b[3])),DateTime.parse(a[4]).compareTo(DateTime.parse(b[4]))][i]
    def i(s='')as String[]?
        return (for x in.f where x[0]==s)[0]

Выход:

#report Balance
   Balance Account Firstname  Lastname           Date      
     $7.95 501     Timmy      Bongo              2014-11-04
   $266.71 166     Chip       Stonesmith         2014-12-15
   $346.22 123     Maree      Jones              2014-12-13
   $893.00 105     William    Greene             2015-01-06
  $1228.73 300     Mary       Galoway            2014-12-28
  $1299.82 888     Alexandria Cooper             2014-12-30
  $2055.44 203     Samantha   Richardson         2014-11-01
  $3422.02 035     Thomas     Breakbone          2015-01-03
$277847.74 422     Henrietta  Throsby-Borashenko 2014-11-21
$956119.66 151     Bruce      Wayne              2014-10-09
#open Clark Kent
001
#print 001
Account Firstname Lastname   Balance Date
001     Clark     Kent         $0.00 2015-02-04
#deposit 001 4530
#withdraw 105 893
#close 105
#report Date
Date       Account Firstname  Lastname              Balance
2014-10-09 151     Bruce      Wayne              $956119.66
2014-11-01 203     Samantha   Richardson           $2055.44
2014-11-04 501     Timmy      Bongo                   $7.95
2014-11-21 422     Henrietta  Throsby-Borashenko $277847.74
2014-12-13 123     Maree      Jones                 $346.22
2014-12-15 166     Chip       Stonesmith            $266.71
2014-12-28 300     Mary       Galoway              $1228.73
2014-12-30 888     Alexandria Cooper               $1299.82
2015-01-03 035     Thomas     Breakbone            $3422.02
2015-02-04 001     Clark      Kent                 $4530.00

Спасибо за вашу запись. Мне пришлось искать Кобру, чтобы увидеть, что это было. Возможно, мне пора выучить другой язык.
Логика Рыцарь

Было бы очень полезно, если бы вы могли добавить пример выходных данных программы (см. Обновленный вопрос). Спасибо.
Логика Найт

@CarpetPython будет сделан сегодня днем.
Οurous

1

Python 2 - 2205 байт

Вот довольно многословная попытка решения.

import sys, time, re
def db(recs):
    text = '\n'.join(' '.join(row) for row in [titles]+recs)
    open('Bank.data', 'wt').write(text+'\n')
def wid(col, recs):
    w = max(len(r[col]) for r in [titles]+recs)
    return w if col == 3 else -w
while 1:
    inp=raw_input('# ').split()
    try:
        cmd = inp.pop(0)
        data = [d.split() for d in open('Bank.data', 'rt').readlines()]
        titles = data.pop(0)
        today = '-'.join('%02u' % v for v in time.localtime()[:3])
        alist = set(int(r[0]) for r in data)
        if cmd == 'open':
            assert re.match(r'[-a-zA-Z]{2,}', inp[0]+inp[1])
            acct = '%03u'%([n for n in range(1, 1000) if n not in alist][0])
            rec = [acct] + inp + ['0.00', today]
            db(data+[rec])
            print acct
        elif cmd == 'withdraw':
            a, m = inp[0], float(inp[1])
            rec = [r for r in data if r[0] == a][0]
            b = float(rec[3])
            assert b >= m
            rec[3] = '%.2f' % (b-m)
            rec[4] = today
            db(data)
        elif cmd == 'deposit':
            a, m = inp[0], float(inp[1])
            rec=[r for r in data if r[0]==a][0]
            rec[3]='%.2f'%(float(rec[3])+m)
            rec[4]=today
            db(data)
        elif cmd=='close':
            rec=[r for r in data if r[0]==inp[0]][0]
            assert int(rec[3])==0
            data=[r for r in data if r!=rec]
            db(data)
        elif cmd=='report':
            for r in data: r[3]='$'+r[3]
            fmtlist=['%'+str(wid(c,data))+'s' for c in range(5)]
            loc=titles.index(inp[0])
            for r in data: r.insert(0,r.pop(loc))
            data.sort(key=lambda x: float(x[0][1:]) if loc==3 else x[0])
            titles.insert(0,titles.pop(loc))
            fmtlist.insert(0,fmtlist.pop(loc))
            for r in [titles]+data: print ' '.join(fmtlist)%tuple(r)
        elif cmd=='print':
            for r in data: r[3]='$'+r[3]
            rec=[r for r in data if r[0]==inp[0]][0]
            fmt=' '.join('%'+str(wid(c,[rec]))+'s' for c in range(5))
            for r in [titles,rec]: print fmt%tuple(r)
        else: raise()
    except:
        print 'failed'

Вот пример используемого приложения:

# report Balance
   Balance Account Firstname  Lastname           Date      
     $7.95 501     Timmy      Bongo              2014-11-04
   $266.71 166     Chip       Stonesmith         2014-12-15
   $346.22 123     Maree      Jones              2014-12-13
   $893.00 105     William    Greene             2015-01-06
  $1228.73 300     Mary       Galoway            2014-12-28
  $1299.82 888     Alexandria Cooper             2014-12-30
  $2055.44 203     Samantha   Richardson         2014-11-01
  $3422.02 035     Thomas     Breakbone          2015-01-03
$277847.74 422     Henrietta  Throsby-Borashenko 2014-11-21
$956119.66 151     Bruce      Wayne              2014-10-09
# open Clark Kent
001
# print 001
Account Firstname Lastname Balance Date      
001     Clark     Kent       $0.00 2015-01-13
# deposit 001 4530
# withdraw 105 893
# close 105
# report Date
Date       Account Firstname  Lastname              Balance
2014-10-09 151     Bruce      Wayne              $956119.66
2014-11-01 203     Samantha   Richardson           $2055.44
2014-11-04 501     Timmy      Bongo                   $7.95
2014-11-21 422     Henrietta  Throsby-Borashenko $277847.74
2014-12-13 123     Maree      Jones                 $346.22
2014-12-15 166     Chip       Stonesmith            $266.71
2014-12-28 300     Mary       Galoway              $1228.73
2014-12-30 888     Alexandria Cooper               $1299.82
2015-01-03 035     Thomas     Breakbone            $3422.02
2015-01-13 001     Clark      Kent                 $4530.00
# 

1

Партия - 1827

Пакет не предназначен для такого рода вещей.

@echo off&setLocal enableDelayedExpansion&set B=Bank.data&echo wscript.echo eval(wscript.arguments(0))>%temp%\eval1.vbs&set Z=goto :EOF&set V=call&set F=for /l %%a in (1,1,
:m
set C=-1&set D=%date:~-4%-%date:~-7,2%-%date:~-10,2%
for /f "tokens=1-5" %%a in (%B%)do set/aC+=1 &set !C!=%%a %%b %%c %%d %%e&set !C!n=%%a&set !C!f=%%b&set !C!s=%%c&set !C!b=%%d&set !C!d=%%e&set A=%%a&set/aA+=1
set/pI="#"
%V% :%I% 2>nul||echo failed&goto m
goto m
:open
echo %A% %1 %2 0.00 %D%>>%B%&echo %A%&%Z%
:close
echo !0!>%B%&%F%!C!)do if "!%%an!" NEQ "%1" (echo !%%a!>>%B%)else if !%%ab! GTR 0.00 echo failed & echo !%%a!>>%B%
%Z%
:deposit
%F%!C!)do if "!%%an!"=="%1" set p=%%a
%V% :c "!%p%b!+%2"
set %p%b=%r%&set %p%d=%D%&%V% :u
%Z%
:withdraw
%F%!C!)do if "!%%an!"=="%1" set p=%%a
%V% :c "!%p%b!-%2"&if "%r:~0,1%"=="-" echo failed&%Z%
set %p%b=%r%&set %p%d=%D%&%V% :u
%Z%
:report
for /l %%a in (1,1,50)do set H= !H!
for /l %%a in (0,1,!C!)do (
%V% :l !%%an!&set %%anl=!l!&if !l! GTR !tn! set/atn=!l!
%V% :l !%%af!&set %%afl=!l!&if !l! GTR !tf! set/atf=!l!
%V% :l !%%as!&set %%asl=!l!&if !l! GTR !ts! set/ats=!l!
%V% :l !%%ab!&set %%abl=!l!&if !l! GTR !tb! set/atb=!l!
)
for /l %%a in (0,1,!C!)do %V% :c "%tn%-!%%anl!"&set sn=!r:~0,-3!&%V% :t !sn!&set pn=!x!&%V% :c "%tf%-!%%afl!"&set sf=!r:~0,-3!&%V% :t !sf!&set pf=!x!&%V% :c "%ts%-!%%asl!"&set ss=!r:~0,-3!&%V% :t !ss!&set ps=!x!&%V% :c "%tb%-!%%abl!"&set sb=!r:~0,-3!&%V% :t !sb!&set pb=!x!&echo !%%an!!pn! !%%af!!pf! !%%as!!ps! !pb!$!%%ab! !%%ad!
%Z%
:l
set S=%1&for /f usebackq %%a in (`Powershell "'!S!'.Length"`)do set l=%%a
%Z%
:t
set x=!H:~0,%1!
%Z%
:u
echo !0!>%B%&%F%!C!)do echo !%%an! !%%af! !%%as! !%%ab! !%%ad!>>%B%&%Z%
:c
for /f %%a in ('cscript //nologo %temp%\eval1.vbs "round(%1,2)"')do set r=%%a
if "%r:~-3,1%" NEQ "." set r=%r%.00

Еще предстоит реализовать функции сортировки (в рамках отчета) и печати.


Было бы очень полезно, если бы вы могли добавить пример выходных данных программы (см. Обновленный вопрос). Спасибо.
Логика Найт

1

STATA 1506

Не пытался играть в гольф слишком много. Я полагал, что статистический язык был бы лучше в этом, но очевидно.

set more off
while 1<2{
qui insheet using Bank.data,delim(" ")clear case
form A %-03.0f
form B %10.2f
form D %-10s
form F %-50s
form L %-50s
g K="$"+string(B,"%10.2f")
di"#",_r(q)
loc s: di %tdCCYY-NN-DD date(c(current_date),"DMY")
if word("$q",1)=="open"{
forv x=0/999{
egen c=anymatch(A),v(`x')
if c<1{
egen m=min(A)
cap expand 2 if A==m,gen(z)
replace A=`x' if A==m&z>0
replace B=0 if A==`x'
replace F=word("$q",2) if A==`x'
replace L=word("$q",3) if A==`x'
replace D="`s'" if A==`x'
di"`x'"
outsheet A-D using Bank.data,delim(" ")replace
continue, br
}
if `x'==999{
di"failed"
}
drop c
}
continue
}
if word("$q",1)=="report"{
ren B R
ren K Balance
if word("$q",2)=="Account"{
so A
l A-L B D,clean noo
}
else if word("$q",2)=="Date"{
so D
l D A-L B,clean noo
}
else if word("$q",2)=="Lastname"{
so L
l L A F B D,clean noo
}
else if word("$q",2)=="Balance"{
so R
l B A-L D,clean noo
}
else if word("$q",2)=="Firstname"{
so F
l F A L B D,clean noo
}
else{
di"failed"
}
continue
}
gen i=real(word("$q",2))
egen p=min(abs(A-i))
if p>0{
di"failed"
continue
}
if word("$q",1)=="close"{
egen c=count(i)
drop if A==i&B==0
qui cou
if c==r(N){
di"failed"
continue
}
}
if word("$q",1)=="print"{
drop Balance
ren K Balance
l A-L B D if A==i,noo clean ab(9)
continue
}
gen j=real(word("$q",3))
if word("$q",1)=="withdraw"{
replace B=B-j if A==i
egen c=min(B)
if c<0{
di"failed"
continue
}
}
if word("$q",1)=="deposit"{
replace B=B+j if A==i
}
replace D="`s'" if A==i
outsheet A-D using Bank.data,delim(" ")replace
}

Было бы очень полезно, если бы вы могли добавить пример выходных данных программы (см. Обновленный вопрос). Спасибо.
Логика Найт

1

C # - 1952 1883

Я покажу некоторые результаты, когда я приеду завтра. На данный момент вот представление:

using System;using System.Collections.Generic;using System.IO;using System.Linq;using S=System.String;using O=System.Func<dynamic,string,string>;class I{char[]c={' '};Action<string>w;Func<S,S,S,S,S,dynamic>n;Func<string>N;List<dynamic>T;private static void Main(string[]a){while(true){Console.Write("# ");new I().Parse(Console.ReadLine());}}I(){w=Console.WriteLine;n=(g,h,i,j,k)=>new{a=g,f=h,l=i,b=j,d=k};N=()=>DateTime.Now.ToString("yyyy-MM-dd");}List<dynamic>G(){return File.ReadAllLines("test.data").Select(l=>l.Split(c)).Select(ac=>n(ac[0],ac[1],ac[2],ac[3],ac[4])).ToList();}void W(){File.WriteAllLines("test.data",T.Select(a=>(S)(a.a+" "+a.f+" "+a.l+" "+a.b+" "+a.d)));}void Parse(string inp){var C=true;try{Func<object,float>v=Convert.ToSingle;Func<string,bool>s=string.IsNullOrEmpty;var i=inp.Split(c);T=G();Func<S,int>F=m=>T.IndexOf(T.FirstOrDefault(a=>a.a==m));C=!s(i[1]);var g=F(i[1]);switch(i[0]){case"open":if(C){int an=0;var cs="000";while(T.Any(A=>cs==A.a)){an++;cs=an.ToString("D3");}T.Add(n(cs,i[1],i[2],"0.00",N()));w(cs);}break;case"withdraw":case"deposit":var D=i[0]=="deposit";C=(D||v(T[g].b)>=v(i[2]));var ba=(v(T[g].b)+v(i[2])*(D?1:-1)).ToString("F");if(C)T[g]=n(T[g].a,T[g].f,T[g].l,ba,N());break;case"close":C=g>-1&&v(T[g].b)<=0;if(C)T.RemoveAt(g);break;case"report":case"print":var X=i[0]=="print";var B=1;O o=(x,p)=>((Type)x.GetType()).GetProperty(p).GetValue(x);O K=(k,j)=>{var r=(j=="b"?"$":"");var P=T.Max(_=>(o(_,j)).Length);return r==""?(o(k,j)).PadRight(P):((B<1?r:"")+(o(k,j))).PadLeft(P+1);};var q=i[1];Action<dynamic,S>U=(u,t)=>{S l=""; foreach(var h in t)l+=K(u,h.ToString())+" "; w(l);};q=q=="Account"?"a":q=="Firstname"?"f":q=="Lastname"?"l":q=="Balance"?"b":q=="Date"?"d":"a"; var V=(q+"afldb".Replace(q,""));U(T.First(),V);B=0;foreach(var M in(X?T.Skip(1).Take(1):T.Skip(1).OrderBy(df=>o(df,q))))U(M,V);break;}W();}catch{}if(!C)w("Failed");}}

Было бы очень полезно, если бы вы могли добавить пример выходных данных программы (см. Обновленный вопрос). Спасибо.
Логика Найт

1

C # - 1870 1881 байт

Злоупотребления usingалиасов Action, Funcисключения для управления потоком и многого другого. Рассматривал использование этого "отчета", не определяющего, как вещи должны быть отсортированы. Bank.data должен использовать разрывы строк Unix, иначе этот код будет нарушен.

Отредактировано для устранения потенциальной проблемы сортировки по полям, отличным от даты и баланса.

using System;using System.Collections.Generic;using System.IO;using System.Linq;using Ac=System.Action;using Cn=System.Console;using F1=System.Func<string,int>;using F2=System.Func<string>;using S=System.String;class P{static void Main(S[] args){S fn="Bank.data";List<S>ad=null;F1 L=(s)=>s.Length;F2 dt=()=>S.Format("{0:yyyy-MM-dd}",DateTime.Now);Func<S,S[]>sp=(s)=>s.Split(' ');Action<S,S>wl=(s,fm)=>Cn.WriteLine(S.Format(fm,sp(s)));Func<S,S>rs=(s)=>{var t=sp(s);t[3]="$"+t[3];return S.Join(" ",t);};F2 fs=()=>{int[]sz={7,9,8,7};ad.Skip(1).ToList().ForEach(b=>{for(int c=0;c<4;c++){sz[c]=Math.Max(sz[c],L(sp(rs(b))[c]));}});return"{0,-"+sz[0]+"} {1,-"+sz[1]+"} {2,-"+sz[2]+"} {3,"+sz[3]+"} {4,-10}";};F1 k=(s)=>sp(ad[0]).ToList().FindIndex(a=>a==s);Ac Sv=()=>File.WriteAllText(fn,S.Join("\n",ad));Ac Ld=()=>ad=File.ReadAllText(fn).Split('\n').ToList();Action<int,S>R=(r,a)=>{var s=sp(ad[r]);s[3]=S.Format("{0:#.00}",Convert.ToDouble(s[3])+Convert.ToDouble(a));s[4]=dt();ad[r]=S.Join(" ",s);};Ac f=()=>wl("failure","{0}");F1 ri=(n)=>{for(int w=1;w < ad.Count;w++){if(ad[w].StartsWith(n))return w;}return -1;};F2 nm=()=>{var s="";for(int i=1;i<1000;i++){s=S.Format("{0:000}",i);if (ri(s)<0)break;}return s;};for(;;){Cn.Write("# ");S i=Cn.ReadLine();var it=sp(i+" ");Ld();var n=ri(it[1]);it=sp(i);var a=new Dictionary<S,Ac>(){{"deposit",()=>R(n,it[2])},{"withdraw",()=>R(n,"-"+it[2])},{"close",()=>(sp(ad[n])[3]==".00"?()=>ad.RemoveAt(n):f)()},{"open",()=>{var nn=nm();ad.Add(S.Format("{0} {1} {2} .00 {3}",nn,it[1],it[2],dt()));wl(nn,"{0}");}},{"print",()=>{wl(ad[0],fs());wl(rs(ad[n]),fs());}},{"report",()=>{var ks=sp(fs()).ToList();var ki=k(it[1]);ks.Insert(0,ks[ki]);ks.RemoveAt(ki+1);var kf=S.Join(" ",ks);wl(ad[0],kf);ad.Skip(1).OrderBy(b=>(ki==3?new S('0',11-L(sp(b)[ki])):"")+sp(b)[ki]).ToList().ForEach(b=>wl(rs(b),kf));}}};try{a[it[0]]();Sv();}catch(Exception){f();}}}}

Выход:

# report Balance
   Balance Account Firstname  Lastname           Date
     $7.95 501     Timmy      Bongo              2014-11-04
   $266.71 166     Chip       Stonesmith         2014-12-15
   $346.22 123     Maree      Jones              2014-12-13
   $893.00 105     William    Greene             2015-01-06
  $1228.73 300     Mary       Galoway            2014-12-28
  $1299.82 888     Alexandria Cooper             2014-12-30
  $2055.44 203     Samantha   Richardson         2014-11-01
  $3422.02 035     Thomas     Breakbone          2015-01-03
$277847.74 422     Henrietta  Throsby-Borashenko 2014-11-21
$956119.66 151     Bruce      Wayne              2014-10-09
# open Clark Kent
001
# print 001
Account Firstname  Lastname              Balance Date
001     Clark      Kent                     $.00 2015-02-03
# deposit 001 4530
# withdraw 105 893
# close 105
# report Date
Date       Account Firstname  Lastname              Balance
2014-10-09 151     Bruce      Wayne              $956119.66
2014-11-01 203     Samantha   Richardson           $2055.44
2014-11-04 501     Timmy      Bongo                   $7.95
2014-11-21 422     Henrietta  Throsby-Borashenko $277847.74
2014-12-13 123     Maree      Jones                 $346.22
2014-12-15 166     Chip       Stonesmith            $266.71
2014-12-28 300     Mary       Galoway              $1228.73
2014-12-30 888     Alexandria Cooper               $1299.82
2015-01-03 035     Thomas     Breakbone            $3422.02
2015-02-03 001     Clark      Kent                 $4530.00
#
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.