Viết một chương trình sắp xếp có vẻ sai nhưng thực sự đúng [đã đóng]


12

Viết chương trình sắp xếp một vectơ số (hoặc bất kỳ loại phần tử nào) trông giống như có một hoặc nhiều lỗi, nhưng thực tế là ổn.

  • Mã phải rõ ràng. Ai đó xem qua mã phải dễ dàng xác định rằng đó là một thuật toán sắp xếp và phải dễ dàng nhầm lẫn một đoạn mã chính xác với một lỗi.
  • Lỗi (rõ ràng) có thể bởi bất cứ điều gì làm cho mã bị hình thành về mặt cú pháp hoặc ngữ nghĩa (ví dụ: làm cho chương trình không biên dịch / chạy, trưng bày UB khi chạy), làm cho chương trình tạo ra kết quả không chính xác, không chấm dứt hoặc không xác định.
  • Mã phải thực sự được định dạng tốt và chương trình phải xác định sản xuất đầu ra chính xác trong một thời gian hữu hạn.
  • Đầu vào có thể được mã hóa cứng trong chương trình hoặc có thể được đọc (từ người dùng, từ tệp, v.v.).
  • Đầu vào được coi là hợp lệ và chương trình không cần thiết để xác minh tính chính xác của đầu vào.
  • Bất kỳ thuật toán sắp xếp được chấp nhận. Cấu trúc dữ liệu để giữ các số không cần thiết phải là một vectơ thực tế. Chương trình có thể được thiết kế để sắp xếp một số lượng biến số hoặc một số lượng cố định (ví dụ: một chương trình để sắp xếp 3 số là ok ). Sắp xếp có thể ổn định hoặc không (lưu ý: một chương trình được thiết kế để thực hiện sắp xếp ổn định có lỗi rõ ràng làm cho sắp xếp không ổn định, nhưng thực tế nó không phải là lỗi: chương trình thực sự sắp xếp ổn định - là một câu trả lời hợp lệ ).
  • bạn có thể gọi bất kỳ chức năng (bao gồm cả chức năng sort) trừ công cụ của bên thứ 3 (trừ khi họ là rộng rãi và lây lan qua sử dụng ví dụ như booscho C++, JQuerycho Javascript- những là ok để sử dụng)
  • chỉ định ngôn ngữ
  • nhận xét trong mã phần trông giống như một lỗi.
  • giải thích những gì lỗi trông giống như làm sai.
  • giải thích (trong hộp spoiler) tại sao nó thực sự không phải là một lỗi.

Đây là một cuộc thi phổ biến. Câu trả lời với hầu hết các phiếu chiến thắng.


Thử thách này đã kết thúc. Người chiến thắng là @Cluless /codegolf//a/30190/11400 với 8 phiếu bầu. Cảm ơn tất cả các đệ trình!

Nếu bạn muốn đến sau khi người chiến thắng được trao, xin vui lòng thêm câu trả lời mới. Bạn ra khỏi cuộc đua, nhưng tất cả chúng ta đều quan tâm để xem câu trả lời thú vị.


Tôi có thể sử dụng booleans nilable thay vì số?
Οurous

vâng, cũng đã chỉnh sửa câu hỏi: bất kỳ loại yếu tố nào
bolov

1
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:


11

C ++

Lấy cảm hứng từ Apple goto fail; lỗi .

#include <vector>
#include <map>
#include <iostream>

/**
 * Sorts a vector of doubles in reverse order using the bucket sort algorithm.
 */
std::vector<double> reverse_bucket_sort(const std::vector<double>& input) {
    // put each element into a bucket as many times as it appears
    std::map<double, int> bucket_counts;
    for (auto it : input)
        ++bucket_counts[it];

    std::vector<double> sorted_elements; // the return value

    // loop until we are done
    while (bucket_counts.size() > 0) {
        // find the largest element
        double maximum = std::numeric_limits<double>::lowest();
        for (auto it : bucket_counts) {
            if (it.first > maximum)
                maximum = it.first;
                maximum = it.first;
        }

        // add the largest element N times to our sorted vector
        for (int i = 0; i < bucket_counts[maximum]; ++i)
            sorted_elements.push_back(maximum);

        // and now erase the bucket
        bucket_counts.erase(maximum);
    }

    return sorted_elements;
}

int main(int argc, const char * argv[]) {
    std::vector<double> test_case = { 0, 1, 2.5, 10, 2.5, 2 };

    std::cout << "unsorted:";
    for (auto it : test_case) std::cout << " " << it;
    std::cout << std::endl;

    std::cout << "sorted:";
    for (auto it : reverse_bucket_sort(test_case)) std::cout << " " << it;
    std::cout << std::endl;

    return 0;
}

Khoảng nửa trang có một lỗi: chúng tôi có một dòng trùng lặp sau khi ifkiểm tra! Chúng tôi sẽ luôn cập nhật tối đa với bất kỳ giá trị cuối cùng nào bucket_count. Rất may chúng tôi ổn. Trong C ++ std::mapđược sắp xếp theo các phím. Vì vậy, chúng tôi chỉ đảo ngược các thùng, đó là những gì chúng tôi muốn.


Bạn đã không sử dụng goto, do đó không có lỗi. (Đề cập đến tất cả những người nói rằng lỗi sẽ không bao giờ xảy ra nếu Apple không sử dụng goto)
user253751

Xin chúc mừng, bạn đã chiến thắng thử thách này bằng cách có nhiều phiếu nhất (8 phiếu sau 7 ngày). Ngoài ra, tôi thực sự thích câu trả lời của bạn vì bạn đã sử dụng một lỗi thực tế.
bolov

8

Python2.x

import random
L = [random.randrange(20) for x in range(20)]
print "Unsorted:", L

def sort(L):
    # terminal case first. Otherwise sort each half recursively and combine
    return L.sort() if L > 1 else sort(L[:len(L)//2]) + sort(L[len(L)//2:])

sort(L)
print "Sorted:", L

Chạy thử nghiệm

list.sorttrả về None, vì vậy phần sau elseNone + None. May mắn thay, điều này không gây ra vấn đề gì vì (L > 1)luôn luôn so sánh danh sách và int True. Hàm luôn luôn trả về Nonevì vậy chúng tôi bỏ qua giá trị trả về và Chỉ cần in Lđã được sắp xếp tại chỗ Việc hợp nhất các nửa đã sắp xếp bằng cách catenation sẽ không hoạt động ngay cả khi việc thực thi đã đến đó.


Xin chúc mừng, bạn đã xếp thứ hai với 6 phiếu sau 7 ngày. Cảm ơn bạn đã gửi.
bolov

5

C

Sử dụng sắp xếp không chính xác - trên hệ thống 64 bit intlà 4 byte và char *8 byte, vì vậy không nên hoạt động.

Mã số:

#include <stdlib.h>
#include <stdio.h>

/* Compare integers to sort in reverse order */
int compare(const void *p, const void *q)
{
    const int *a = p;
    const int *b = q;

    return *b - *a;
}

int main()
{
    char *strings[] = {"B", "Que", "Ro", "Sum", "T"};
    int i;

    /* Let's use the integer compare to sort strings */
    qsort(&strings, sizeof(strings) / sizeof(char *), sizeof(char *), compare);

    /* Output the sorted results */
    for (i = 0; i < sizeof(strings) / sizeof(char *); i++)
        printf("%s\n", strings[i]);

    return 0;
}

Xây dựng:

$ gcc -o sort-no-sort sort-no-sort.c 

Chạy:

$ ./sort-no-sort 
T
Sum
Ro
Que
B

Đúng, sắp xếp ổn rồi!

Năm điều đang diễn ra: 1) qsortchuyển con trỏ đến số nguyên, có cùng kích thước với con trỏ tới ký tự. 2) Các chuỗi có độ dài không quá bốn byte (ba + một terminator) = kích thước của một số nguyên, mà thường trình sắp xếp hạnh phúc coi là một số nguyên. 3) Hầu hết các trình biên dịch buộc căn chỉnh cấu trúc dữ liệu, do đó các chuỗi ngắn hơn chiếm cùng một không gian. Bất kỳ lớn hơn mặc dù và được chuẩn bị cho thất bại. 4) Tính cuối cùng. 5) Không khởi tạo byte nội bộ.


Cảm ơn bạn đã gửi. Bạn đã đặt thứ 3. Chúc mừng!
bolov

2

Rắn hổ mang

class Program
    var _target as List<of bool?> = [true, true, false, true, true, nil, nil, false, true, nil, true]
    def main
        .sort(_target)
        print _target
    def sort(target as List<of bool?>)
        for i in target.count, for n, in target.count -1, if target[n] <> target[n + 1] and (target[n] or target[n + 1] == nil), target[n], target[n + 1] = target[n + 1], target[n]
            #should return sorted as [nil][false][true]

Ôi trời, tôi dường như đã gán sai n... và làm thế nào mà tất cả các dấu phẩy đến đó!?

Khi nđược gán, trình biên dịch giả định rằng nó được cung cấp nửa đầu của cặp giá trị khóa (do dấu phẩy), nhưng không có cặp giá trị khóa nào nên trình biên dịch không phàn nàn khi không thể gán nửa sau của nó với một biến không tồn tại. Điều này dẫn đến việc nchỉ cần đưa ra giá trị khóa .. trong trường hợp này là số chỉ mục. Tất cả các dấu phẩy ngoài vị trí khác trong dòng cuối cùng thực sự là một phần của cú pháp Cobra tiêu chuẩn.


Cảm ơn bạn đã gửi. Bạn đã đặt thứ 3. Chúc mừng!
bolov

2

Java

public final class WeirdSort {
    public static void main(final String[] args) {

        //Random
        final Random random = new Random(441287210);

        //Some numbers:
        final List<Integer> list = new ArrayList<Integer>();
        list.add(9);
        list.add(11);
        list.add(3);
        list.add(5);
        list.add(7);

        //Sort randomly:
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(final Integer o1, final Integer o2) {
                return (o1 - o2) + random.nextInt(10);
            }
        });

        //Print
        for(final Integer i:list) {
            System.out.print(i + " ");
        }
    }
}

Prints: 3 5 7 9 11 

Hoạt động vì giá trị ngẫu nhiên cụ thể này trả về '1' cho 10 kết quả đầu tiên


1
Bạn sử dụng ngôn ngữ nào
Knerd

Java, xin lỗi đã quên đề cập đến điều đó (chỉnh sửa).
Roy van Rijn

2

Perl

Nhà thầu những ngày này! Họ không biết rằng<=> (còn gọi là "tàu vũ trụ") chỉ được sử dụng để sắp xếp số?

Và tại sao họ lại so sánh các nhà khai thác?

Làm thế nào mà mã này thậm chí vượt qua các bài kiểm tra nghiêm ngặt của chúng tôi ?? !! Nó thậm chí sử dụng strictwarnings!

use strict;
use warnings;

sub asciibetically { 0-($a lt $b) || 0+($a gt $b) || <=><=><=> }
                                                   #  ^  ^  ^
                                                   # What?? How did Perl even compile??!!

my @sorted = sort asciibetically qw( bravo charlie alpha );

print "@sorted";   # "alpha bravo charlie"
                   # And how come it works??!!

Tại sao Perl biên dịch

<=>Toán tử thực sự duy nhất là cái ở giữa. Hai cái kia chỉ là một cách viết khác glob("="). Điều này có nghĩa là <=><=><=>(biệt danh "hạm đội không gian") ước tính 0.


Tại sao nó hoạt động

Các asciibeticallychương trình con là một thực hiện các chuỗi so sánh cmpđiều hành: Binary " cmp" lợi nhuận -1, 0hoặc 1tùy thuộc vào việc lập luận trái là stringwise ít hơn, bằng hoặc lớn hơn đối số đúng.


3
Chà, Perl trông giống như một lỗi dù sao đối với tôi ...
chill0r
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.