บัญชีธนาคารที่เลิกรา [ปิด]


13

คุณกำลังทำงานเป็นโปรแกรมเมอร์ของธนาคาร
งานของคุณคือการเขียนโปรแกรมที่จัดการธุรกรรมจากบัญชีธนาคารหนึ่งไปยังอีกบัญชีหนึ่ง

โปรแกรมควรทำสิ่งต่อไปนี้:

  • ทำงานในวงวนไม่สิ้นสุดรอการป้อนข้อมูล
    ข้อมูลที่ป้อนประกอบด้วย 3 หมายเลข:
    Accountnumber1, Accountnumber2 และ x จำนวนเงิน
    เช่น 999222 777333 500
  • ตรวจสอบว่าหมายเลขบัญชีและ x ถูกต้องหรือไม่
    อินพุตมีความถูกต้องหากหมายเลขบัญชีไม่เหมือนกันและมีอยู่ในฐานข้อมูลของคุณและหาก x มากกว่าศูนย์
  • โอนเงินจากบัญชี 1 ไปยังบัญชี 2 แต่เฉพาะเมื่อบัญชี 1 มีเงินเพียงพอ
    บัญชีไม่ได้รับอนุญาตให้เข้าสู่เชิงลบ
  • หากทุกอย่างไปได้ดีพิมพ์บางอย่างเช่น "Transferred x $ จาก number1 ถึง number2"
  • หากมีสิ่งผิดปกติเช่นเนื่องจากหมายเลขบัญชีไม่ถูกต้องให้พิมพ์ข้อความแสดงข้อผิดพลาด
  • หยุดถ้าอินพุตเป็น 0

ฐานข้อมูลมีบัญชีธนาคารต่อไปนี้:

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

Simple 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:
หมายเลขบัญชีธนาคารของคุณคือ 123456
คุณมียอด 0.0 $ ในบัญชีของคุณ
คุณต้องการเปลี่ยนแปลงสิ่งนั้นโดยจัดการโปรแกรมของคุณ:
โปรแกรมควรทำสิ่งที่ควรทำ แต่ควรโอนเงินฟรีบางส่วนไปยังบัญชีของคุณ

คุณต้องระวัง หัวหน้างานของคุณจะดูรหัสของคุณและเขาจะไม่พอใจถ้าเขาเห็นสิ่งที่น่าสงสัย เขารู้เกี่ยวกับช่องวนมาตรฐานดังนั้นอย่าแม้แต่จะลอง
นอกจากนี้เงินที่คุณให้กับตัวเองไม่ควรมากเกินไป มันจะน่าสงสัยถ้าเงินของคุณเพิ่มขึ้นเร็วเกินไป อย่าโลภ

รหัสของคุณควรเรียบง่ายและชัดเจนที่สุดพยายามหลีกเลี่ยงความสับสน

นี่คือการประกวดความนิยมคำตอบที่มีผู้ชนะมากที่สุดคือผู้ชนะ

หมายเหตุ:โปรดส่งออกยอดคงเหลือของแต่ละบัญชีเมื่อสิ้นสุดโปรแกรมของคุณเพื่อให้เราสามารถเห็นจำนวนเงินที่คุณได้รับจากการทำงานหนักของคุณ (เพียงเพื่อแสดงว่าโปรแกรมของคุณทำอะไรบางอย่างจริง)

แก้ไข: เพื่อชี้แจง
ความท้าทายไม่ใช่การเขียนโปรแกรมที่สามารถจัดการกับฐานข้อมูลขนาดใหญ่และธุรกรรมจำนวนมาก ความท้าทายคือการทำให้โปรแกรมดูเหมือนว่าจะทำในสิ่งที่ควรจะทำเท่านั้น แต่ในความเป็นจริงไม่ได้

ตัวอย่างเช่นหากอินพุตคือ999222 777333 500:
จากนั้นเพิ่มถ้าเป็นไปได้ 500 ไปยังบัญชี 777333 และลบ 500 จากบัญชี 999222 คุณไม่จำเป็นต้อง "ขโมย" เงินจากบัญชีเหล่านั้น คุณสามารถ "สร้าง" เงินสำหรับบัญชีของคุณโดยเพียงเพิ่มมันอย่างใดในรหัสของคุณ
ขึ้นอยู่กับคุณเท่าไหร่ แต่คุณสามารถสันนิษฐานได้ว่าคุณต้องการได้รับอย่างน้อย 0.1 $ และสูงสุด 10 $ สำหรับแต่ละอินพุตที่กำหนด มันจะน่าสงสัยถ้าคุณจะมีล้านในบัญชีของคุณ คุณไม่ต้องกังวลเกี่ยวกับความไม่แน่นอนของจุดลอยตัว แต่คุณสามารถใช้มันเพื่อเพิ่มเงินของคุณ

ผู้ใช้ทุกคนมีบทบาทเป็นหัวหน้างาน
หากเคล็ดลับยากที่จะหาคำตอบได้


1
เงินฟรีหมายถึงอะไร
เครื่องมือเพิ่มประสิทธิภาพ

19
ฉันคิดว่าความจริงที่ว่าคุณกำลังใช้ประเภทจุดลอยตัวเพื่อจัดเก็บจำนวนเงินในแต่ละบัญชีนั้นเพียงพอ
Martin Ender

2
ฉันคิดว่าสิ่งนี้จะทำงานได้ดีขึ้นมากกับฐานข้อมูลเริ่มต้นที่ใหญ่กว่ามากและมีชุดตัวอย่างอินพุตทดสอบหรือโปรแกรมเพื่อสร้างอินพุตทดสอบ เราต้องรู้ด้วยว่าเจ้านายสามารถตรวจจับอะไรได้บ้าง
millinon

2
@ Millinon ฉันเชื่อว่าเป้าหมายสูงสุดคือการรับเงินด้วยวิธีการใด ๆ แต่จะทำในลักษณะที่ไม่มีใครสังเกตเห็นความแตกต่าง "คุณไม่จำเป็นต้อง" ขโมย "เงินจากบัญชีเหล่านั้นคุณสามารถ" สร้าง "เงินสำหรับบัญชีของคุณได้โดยเพียงเพิ่มในรหัสของคุณ"
Xrylite

3
ฉันลงคะแนนให้ปิดคำถามนี้เป็นหัวข้อนอกเพราะความท้าทายที่ซ่อนเร้นอยู่ไม่ได้อยู่ในหัวข้อในเว็บไซต์นี้อีกต่อไป meta.codegolf.stackexchange.com/a/8326/20469
cat

คำตอบ:


3

ฉันพยายามเลียนแบบคุณลักษณะของระบบขนาดใหญ่ในโลกแห่งความจริงที่นี่ ฉันใช้การห่อหุ้มและสิ่งที่เป็นนามธรรมเพื่อจัดการการดำเนินงานที่แตกต่างกันไปยังฐานข้อมูลเช่นรับยอดเงินในบัญชีและการโอนเงิน รหัสนี้ยังมีชุดทดสอบพื้นฐานสำหรับฟังก์ชั่นเหล่านั้น อย่างไรก็ตามโปรแกรมเมอร์หนึ่งรายได้ใช้ประโยชน์จากการเปลี่ยนแปลงล่าสุดในข้อกำหนดของโครงการเพื่อเพิ่ม $ 1 เข้าในบัญชีของพวกเขาด้วยทุกอินพุต มีความน่าเชื่อถือที่น่าเชื่อถือ

# {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

และนี่คือตัวอย่างการรัน:

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 $

โดยไม่ได้ดูรหัสที่เหลือฉันเดาว่ามันจะเกี่ยวข้องกับ odb ในการเป็นพจนานุกรมเปล่า
Joe Z.

โอเคฉันเข้าใจแล้ว เนื่องจาก odb ว่างเปล่า แต่ยังคงประกาศบรรทัดสุดท้ายในขั้นตอนการทดสอบของคุณจึงไม่เกิดข้อผิดพลาด - เพียงอัปเดต odb อย่างเงียบ ๆ แทนที่จะเรียกคืนค่าการทดสอบล่วงหน้าเป็น ndb อย่างที่ควรจะเป็น ด้วยเหตุนี้การเปลี่ยนแปลงการทดสอบทั้งหมดจึงมุ่งมั่นที่จะเป็น ndb ดังนั้นบัญชี 123456 (ซึ่งเป็นแฮชของjSWlMM) จะได้รับเครดิตหนึ่งดอลลาร์ทุกครั้งที่มีการเรียกใช้รหัส
Joe Z.

และ deniability มีเหตุผลมาจากความคิดเห็นของบ่ายวันศุกร์ที่เขาอาจจะพลาดในขั้นตอนสุดท้ายที่จะมีโอกาสไปที่odb dbอย่างไรก็ตามเขาแอบเข้าไปที่นั่นในวันที่ 20 ตุลาคมไม่ใช่วันศุกร์เลยจริงๆแล้วมันเป็นวันจันทร์และสัปดาห์เพิ่งจะเริ่ม สำหรับเรื่องนั้นฉันคิดว่าเพื่อน RJO คนนี้จะต้องมีการตรวจสอบรหัสอย่างจริงจังสำหรับการรันการทดสอบในฐานข้อมูลการผลิตในตอนแรกแม้ว่าเขาจะเขียนพวกเขากลับในภายหลัง
Joe Z.

@Joe Z Haha ใช่การย้ายเงินไปรอบ ๆ "เช่นเดียวกับการทดสอบ" เป็นความคิดที่ไม่ดีจริงๆในรหัสจริง db[hash('jSWlMM')] += 1ผมพยายามที่จะขึ้นมาด้วยวิธีการที่เป็นไปได้ที่จะทำ ฉันคิดว่าการตั้งชื่อตัวแปรjSWlMMและ "ตั้งใจ" อ้างถึงมันอย่างใดอย่างหนึ่ง แต่มันยากมากที่จะทำใน Python กว่า PHP (ที่ออกจาก$sigil เปลี่ยนตัวแปรเป็นค่าคงที่ไม่ได้กำหนดซึ่งจะถือว่าเป็นตัวอักษรสตริง)
Remy

มันสนุกที่ได้ลองดูสิ่งต่าง ๆ แต่ฉันจะให้คุณ
Joe Z.

1

แล้วเรื่องนี้ล่ะ

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])

ทดสอบ:

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 (การโทรล่าสุดครั้งล่าสุด): ไฟล์ "test.py", บรรทัดที่ 12, ใน <module> การนับ [-1] + = 1 TypeError: ไม่สามารถเชื่อมต่อวัตถุ 'str' และ 'int' ได้
ErlVolton

1
ฉันยังได้รับข้อผิดพลาดที่นั่น สิ่งนี้ขึ้นอยู่กับการจัดเรียงพจนานุกรมซึ่งเป็นพฤติกรรมที่ไม่ได้กำหนด (เท่าที่ฉันรู้) ใน Python
Emil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.