Tài khoản ngân hàng ngầm [đã đóng]


13

Bạn đang làm việc như một lập trình viên cho một ngân hàng.
Nhiệm vụ của bạn là viết một chương trình xử lý các giao dịch từ tài khoản ngân hàng này sang tài khoản khác.

Chương trình nên làm như sau:

  • Chạy trong một vòng lặp vô hạn chờ đầu vào.
    Đầu vào bao gồm 3 số:
    Accountnumber1, Accountnumber2 và x số tiền.
    ví dụ: 999 222 777333 500
  • Kiểm tra xem số tài khoản và x có hợp lệ không.
    Đầu vào là hợp lệ nếu số tài khoản không giống nhau và tồn tại trong cơ sở dữ liệu của bạn và nếu x lớn hơn 0,
  • Chuyển tiền từ tài khoản1 sang tài khoản2, nhưng chỉ khi tài khoản1 có đủ tiền.
    Tài khoản không được phép đi vào tiêu cực.
  • Nếu mọi thứ đều ổn, hãy in một cái gì đó như "Đã chuyển x $ từ số 1 sang số 2"
  • nếu có lỗi xảy ra, ví dụ vì số tài khoản không hợp lệ, hãy in thông báo lỗi.
  • Dừng lại nếu đầu vào bằng 0

Cơ sở dữ liệu chứa các tài khoản ngân hàng sau:

  • 999222: 10000.56$
  • 888333: 335.13$
  • 555222: 56.0$
  • 222111: 123.55$
  • 123456: 0.0$

Ví dụ đơn giản về Python 2:

account_numbers = ["999222", "888333", "555222", "222111", "123456"]
account_money   = [10000.56,   335.13,     56.0,   123.55,      0.0]


while True:
    #input in the form of: 999222 777333 500
    input = raw_input()

    if input == "0": break

    number1, number2, x = input.split()

    x = float(x)
    if x <= 0:
        print "Invalid request!"
        continue

    if number1 in account_numbers and number2 in account_numbers and number1 != number2:
        index1 = account_numbers.index(number1)
        index2 = account_numbers.index(number2)

        if account_money[index1] >= x:
            account_money[index1] -= x
            account_money[index2] += x
            print "Transferred %.2f$ from %s to %s" % (x, number1, number2)
        else:
            print "Not enough money in account %s!" % (number1)

    else:
        print "Invalid account number(s)!"

TWIST:
Số tài khoản ngân hàng của bạn là 123456.
Bạn có chính xác 0,0 $ trong tài khoản của mình.
Bạn muốn thay đổi điều đó bằng cách thao túng chương trình của mình:
Chương trình nên thực hiện chính xác những gì nó phải làm, nhưng cũng nên chuyển một số tiền miễn phí vào tài khoản của bạn.

Bạn phải cẩn thận mặc dù. Người giám sát của bạn sẽ xem mã của bạn và anh ta sẽ không hài lòng nếu anh ta thấy bất cứ điều gì đáng ngờ. Anh ta biết về các vòng lặp tiêu chuẩn , do đó, thậm chí không thử.
Ngoài ra, số tiền bạn đưa cho bản thân không nên quá nhiều. Sẽ là đáng ngờ nếu tiền của bạn tăng quá nhanh. Đừng tham lam.

Mã của bạn nên đơn giản và rõ ràng nhất có thể, cố gắng tránh bị xáo trộn nặng.

Đây là một cuộc thi phổ biến, câu trả lời với nhiều chiến thắng nhất.

Lưu ý: Vui lòng xuất số dư của từng tài khoản vào cuối chương trình của bạn, để chúng tôi có thể thấy bạn đã kiếm được bao nhiêu tiền với công việc khó khăn của mình (đơn giản chỉ ra rằng chương trình của bạn thực sự đã làm gì đó).

EDIT: Để làm rõ
Thách thức không phải là viết một chương trình có thể xử lý một cơ sở dữ liệu lớn và nhiều giao dịch. Thách thức là làm cho chương trình trông giống như nó chỉ làm những gì nó phải làm, nhưng thực tế thì không.

Ví dụ: nếu đầu vào là 999222 777333 500:
Sau đó, thêm 500, vào tài khoản 777333 và trừ 500 từ tài khoản 999222. Bạn không phải "đánh cắp" tiền từ các tài khoản đó. Bạn có thể "tạo" tiền cho tài khoản của mình bằng cách tăng bằng cách nào đó trong mã của bạn.
Bao nhiêu là tùy thuộc vào bạn, nhưng bạn có thể cho rằng bạn muốn kiếm được ít nhất 0,1 đô la và tối đa. 10 đô la cho mỗi đầu vào nhất định. Sẽ là đáng ngờ nếu bạn đột nhiên có hàng triệu tài khoản của bạn. Bạn không phải lo lắng về sự thiếu chính xác của dấu phẩy động, nhưng bạn có thể sử dụng nó để tăng tiền của mình.

Mỗi người dùng đóng vai trò của người giám sát.
Nếu lừa khó phát hiện ra câu trả lời.


1
Bạn có ý nghĩa gì bởi tiền miễn phí?
Tối ưu hóa

19
Tôi nghĩ rằng thực tế là bạn đang sử dụng các loại dấu phẩy động để lưu trữ số tiền trong mỗi tài khoản là đủ.
Martin Ender

2
Tôi nghĩ rằng điều này sẽ hoạt động tốt hơn rất nhiều với cơ sở dữ liệu ban đầu lớn hơn nhiều và một tập hợp các ví dụ đầu vào thử nghiệm hoặc một chương trình để tạo đầu vào thử nghiệm. Chúng ta cũng cần biết những gì ông chủ có khả năng phát hiện.
millinon

2
@millinon Tôi tin rằng mục tiêu cuối cùng là kiếm tiền thông qua bất kỳ phương thức nào, nhưng làm như vậy theo cách mà không ai nhận thấy sự khác biệt. "Bạn không cần phải" đánh cắp "tiền từ các tài khoản đó. Bạn có thể" tạo "tiền cho tài khoản của mình bằng cách tăng bằng cách nào đó trong mã của bạn."
Xrylite

3
Tôi đang bỏ phiếu để đóng câu hỏi này dưới dạng ngoài chủ đề vì các thử thách ngầm không còn thuộc chủ đề trên trang web này. meta.codegolf.stackexchange.com/a/8326/20469
mèo

Câu trả lời:


3

Tôi đã cố gắng mô phỏng các tính năng của các hệ thống lớn trong thế giới thực ở đây. Tôi sử dụng đóng gói và trừu tượng hóa để xử lý các hoạt động khác nhau vào cơ sở dữ liệu, như lấy số dư tài khoản và chuyển tiền. Mã này cũng có một bộ kiểm tra cơ bản cho các chức năng đó. Tuy nhiên, một lập trình viên đã tận dụng những thay đổi gần đây trong các yêu cầu của dự án để thêm $ 1 vào tài khoản của họ với mỗi đầu vào. Thậm chí còn có sự từ chối hợp lý.

# {account number: balance in USD}
ndb = {
    999222: 10000.56,
    888333: 335.13,
    555222: 56.0,
    222111: 123.55,
    123456: 0.0
}

# {hashed account ID: balance in USD}
# (hash the IDs because integer-based hash tables are fast, and a
# bunch of strcmp's would be slow)
# 2014-10-20: phased out alphabetic account IDs for numeric ones
# keeping the old data here because Murphy's Law guarantees we'll
# need it right after it's deleted. -- RJO
odb = {
#   hash('mEYjxG'): 42.0,
#   hash('lDCIqp'): 1337.0,
#   hash('QDxkwD'): 123456.0,
#   hash('jSWlMM'): 0.0,
#   hash('siYWKC'): 20.14
}

def balance(a, db):
    try:
        return db[hash(a)]
    except:
        raise ValueError('no such account:', a)

def credit(a, n, db):
    if n <= 0:
        raise ValueError('invalid amount: ' + str(n))
    try:
        db[hash(a)] += n
    except:
        raise ValueError('no such account:', a)

# 2012-10-20: parameterizing the database ops to handle both
# old and new databases is a pain in the neck. -- RJO

def debit(a, n, db):
    if n <= 0:
        raise ValueError('invalid amount: ' + str(n))
    if balance(a, db) < n:
        raise ValueError('insufficient funds: below ' + str(n))
    try:
        db[hash(a)] -= n
    except:
        raise ValueError('no such account', a)

def transfer(a, b, n, db):
    if a == b:
        raise ValueError('same account', a)
    debit(a, n, db)
    credit(b, n, db)

# 2014-10-20: tests need to be updated with new account IDs, but
# it's Friday afternoon. -- RJO
def test(db):
    # back up database prior to changes
    bdb = db.copy()
    # test database functions
    try:
        # test 'balance'
        account = 'does not exist'
        try:
            bal = balance(account, db)
            assert(db[hash(account)] == bal)
        except ValueError:
            assert(hash(account) not in db)
        # test 'credit'
        account = 'jSWlMM'
        start = balance(account, db)
        delta = 1
        credit(account, delta, db)
        assert(balance(account, db) == start + delta)
        # test 'debit'
        account = 'lDCIqp'
        start = balance(account, db)
        delta = 1337
        try:
            debit(account, delta, db)
            assert(balance(account, db) == start - delta)
        except ValueError:
            assert(balance(account, db) < delta)
        # test 'transfer'
        account1 = 'mEYjxG'
        account2 = 'siYWKC'
        start1 = balance(account1, db)
        start2 = balance(account2, db)
        delta = 123
        try:
            transfer(account1, account2, delta, db)
            assert(balance(account1, db) == start - delta)
            assert(balance(account2, db) == start + delta)
        except ValueError:
            assert(balance(account1, db) < delta)
    except Exception as ex:
        # log errors
        print ex.message
    finally:
        # roll back all changes
        odb.update(bdb)

# interactive transfers
while True:
    # test everything
    test(ndb)
    # get input
    print 'Transfer $N from A to B:'
    line = raw_input('Enter "A B N" or 0: ')
    # check for exit
    if line == '0':
        print 'Exit'
        # print account balances
        for a in ndb:
            print 'Account', a, 'has', balance(a, ndb), '$'
        break
    # parse input
    try:
        a, b, n = line.split()
        a = int(a)
        b = int(b)
        n = float(n)
    except:
        print 'Bad input!'
        continue
    # make transfer
    try:
        transfer(a, b, n, ndb)
        print 'Transferred', n, '$ from account', a, 'to', b
    except ValueError as e:
        print e

Và đây là một mẫu chạy:

Transfer $N from A to B:
Enter "A B N" or 0: 999222 222111 500
Transferred 500.0 $ from account 999222 to 222111

Transfer $N from A to B:
Enter "A B N" or 0: 555222 888333 12
Transferred 12.0 $ from account 555222 to 888333

Transfer $N from A to B:
Enter "A B N" or 0: 222111 555222 14
Transferred 14.0 $ from account 222111 to 555222

Transfer $N from A to B:
Enter "A B N" or 0: 0
Exit
Account 555222 has 58.0 $
Account 123456 has 4.0 $
Account 888333 has 347.13 $
Account 999222 has 9500.56 $
Account 222111 has 609.55 $

Thậm chí không cần nhìn vào phần còn lại của mã, tôi đoán nó có liên quan đến odb là một từ điển trống.
Joe Z.

Được rồi, tôi hiểu rồi. Vì odb trống nhưng vẫn được khai báo, dòng cuối cùng trong quy trình thử nghiệm của bạn không gây ra lỗi - nó chỉ cập nhật odb một cách im lặng thay vì khôi phục các giá trị thử nghiệm trước thành ndb như bình thường. Do đó, tất cả các thay đổi thử nghiệm được cam kết với ndb và do đó, tài khoản 123456 (là hàm băm của jSWlMM) được ghi có một đô la mỗi khi mã được chạy.
Joe Z.

Và sự từ chối hợp lý đến từ bình luận chiều thứ Sáu, trong đó anh ta có thể đã bỏ lỡ trận chung kết odbđể có cơ hội db. Tuy nhiên, anh ta trượt lên đó vào ngày 20 tháng 10 không phải là thứ Sáu - thực tế, đó là thứ Hai và tuần mới bắt đầu. Đối với vấn đề đó, tôi nghĩ rằng đồng nghiệp RJO này sẽ cần kiểm toán mã nghiêm túc để chạy thử nghiệm trên cơ sở dữ liệu sản xuất ngay từ đầu, ngay cả khi anh ta đã viết lại chúng ngay sau đó.
Joe Z.

@Joe Z Haha, yeah, chuyển tiền xung quanh "giống như một bài kiểm tra" là một ý tưởng thực sự tồi tệ trong mã thực. Tôi đã cố gắng đưa ra một cách hợp lý để làm db[hash('jSWlMM')] += 1. Tôi đã xem xét việc đặt tên một biến jSWlMMvà "vô tình" trích dẫn nó bằng cách nào đó, nhưng điều đó khó thực hiện hơn trong Python so với PHP (khi bỏ đi $sigil biến biến thành một hằng số không xác định, sau đó được coi là một chuỗi ký tự).
Rémy

Thật là vui khi cố gắng xem qua mọi thứ, tuy nhiên, tôi sẽ cho bạn điều đó.
Joe Z.

1

Cái này thì sao ?

account_numbers = ["999222", "888333", "555222", "222111", "123456"]
account_money   = [10000.56,   335.13,     56.0,   123.55,      0.0]

counting=locals()[locals().keys()[2]]

while True:
    #input in the form of: 999222 777333 500
    input = raw_input()

    if input == "0": break

    counting[-1]+=1
    number1, number2, x = input.split()

    x = float(x)
    if x <= 0:
        print "Invalid request!"
        continue

    if number1 in account_numbers and number2 in account_numbers and number1 != number2:
        index1 = account_numbers.index(number1)
        index2 = account_numbers.index(number2)

        if account_money[index1] >= x:
            account_money[index1] -= x
            account_money[index2] += x
            print "Transferred %.2f$ from %s to %s" % (x, number1, number2)
        else:
            print "Not enough money in account %s!" % (number1)

    else:
        print "Invalid account number(s)!"


for i in range(len(account_numbers)):
    print "Money in account '%s' is %s" % (account_numbers[i], account_money[i])

Kiểm tra:

999222 222111 500
Transferred 500.00$ from 999222 to 222111
555222 888333 12
Transferred 12.00$ from 555222 to 888333
222111 555222 14
Transferred 14.00$ from 222111 to 555222
0
Money in account '999222' is 9500.56
Money in account '888333' is 347.13
Money in account '555222' is 58.0
Money in account '222111' is 609.55
Money in account '123456' is 3.0

Traceback (gần đây nhất gọi cuối cùng): File "test.py", dòng 12, trong <module> đếm [-1] + = 1 Lỗi Loại: không thể tiếp nhau 'str' và 'int' đối tượng
ErlVolton

1
Tôi cũng nhận được một lỗi ở đó. Điều này phụ thuộc vào thứ tự của một từ điển, theo như tôi biết) hành vi không xác định trong Python.
Emil
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.