Ноябрьский конкурс по функциональному программированию
|
3 Ноя, 2011 @ 07:20
|
|---|
Итак, коллеги и любители функционального программирования и прочих мозгодробительных технологий. Как было обещано ранее, сегодня объявляю старт ноябрьского конкурса по функциональному программированию. Задачу нам подогнал многоуважаемый Адепт, за что ему отдельный низкий поклон и всяческая благодарность.
Условия и вопрос задачи:
Дан индикатор, состоящий из n лампочек, которые могут гореть или не гореть. Дан алфавит из k символов, которые закодированы различными комбинациями горящих и не горящих лампочек на индикаторе. Необходимо определить максимальное число лампочек индикатора p (p <= n) и указать эти лампочки, которые, если и перегорят, то не влияют на однозначное распознавание всех символов алфавита. В качестве конкретных примеров индикатора и закодированных символов алфавита можно привести:
1. Семипозиционный индикатор «электронная цифра» и десять арабских цифр:
 2. Девятипозиционный индикатор, используемый при написании цифр индекса на почтовых отправлениях:
 Как вы понимаете, это уже задача чисто на программирование, ибо перебирать все варианты вручную довольно затруднительно. Так что дерзайте — реализуйте свои программы и публикуйте ответы (вместе с листингами или ссылками на них) в комментариях.
На решение задачи отводятся выходные. В понедельник где-то в первой половине дня я раскрою комментарии и начну проверять общность алгоритмов. Буду задавать дополнительные вопросы. По результатам рассмотрения определю победителей. Но в любом случае, как это у меня принято, все участники, которые показали какие-либо результаты, получат те или иные призы. Которых, кстати, стало больше по сравнению с предыдущими конкурсами. Так что в путь.
Ну и по условиям получения призов — москвичи смогут со мной встретиться лично, немосквичи получат призы по почте, но при этом надо будет оплатить почтовые расходы. Все, кто будет претендовать на нематериальные призы, получат их по электронной почте, не сходя со своего рабочего места.
Если кому-то что-то не понятно в условии, прошу вопросы задавать в комментариях. Такие вопросы и ответы на них будут раскрываться сразу, чтобы у всех были равные условия борьбы. Так что подписывайтесь на комментарии к этой записи.
Ну и традиционно этот конкурс посвящается Дню Народного Единства.
Дополнение 1: 14:50 06.11.2011 комментарии раскрыты. Начинаем проверку общности алгоритмов.
Дополнение 2: 13:40 07.11.2011 конкурс завершён. Подводятся результаты, определяются победители.
Дополнение 3: 07:45 08.11.2011 результаты подбиты. Объявление здесь.
Предыдущие конкурсы: 1. Задача о возрастах детей математика: условие, решение. 2. Кто на ком женат: условие, решение. 3. Задачи о переправах: условие, решение.
|
Теория плотных упаковок в применении к кодированию с восстановлением ошибок. Задача решена давно. Например, в кодах Рида-Соломона. Не интересно.
Это прекрасно. Но за подобные комментарии призы не вручаются.
Видимо я тупой, но условия задачи я не понял.
Вот у нас есть семь лампочек в индикаторе в первом примере, так? Сколько из них может перегореть (и какие именно) так, чтобы все десять цифр всё ещё однозначно распознавались? Из все вариантов таких комбинаций перегораний надо выбрать те, где количество перегоревших лампочек максимально.
Так понятней?
Максимальное число лампочек - UINT64MAX (если писать на C)
минимальное, конечно, найти труднее.
Можно. Критерии оценки решения всё равно на этот раз будут иные :)
какие ограничения на n,k?
Теоретически, нет. Но для решения практических задач Вы можете их ограничить. По крайней мере, Вам надо рассмотреть два примера, которые я привёл.
Комментарии раскрыты, начинаем проверку общности предложенных алгоритмов. Четыре с половиной года назад вот здесь я задавал интересный вопрос. При помощи разработанной Вами программы прошу исследовать различные комбинации начертаний цифр индекса и ответить на вопрос: какое начертание наиболее устойчиво к помехам? Необходимо показать это при помощи строгих вычислений. Дерзайте!
| From: | morrom |
| Date: |
Ноябрь, 3, 2011 10:41 (UTC) |
|
|
|
|
(Link) |
|
Дано k неповторяющихся двоичных последовательностей длины n. Найти такую последовательность длины n с минимальным количеством ненулевых битов, что результатом применения этой последовательности в качестве маски операции AND к каждой последовательности из заданного набора будет также набор неповторяющихся последовательностей длины n.
Язык - Mathematica. Алгоритм лобовой, но на небольших числах должен нормально работать. // Число лампочек n = 7; // Список списков используемых лампочек в кодов символов (этот список конкретно для семисегментного индикатора) - далее список кодов list = {{1, 2, 3, 4, 5, 6}, {3, 4}, {2, 3, 5, 6, 7}, {2, 3, 4, 5, 7}, {1, 3, 4, 7}, {1, 2, 4, 5, 7}, {1, 2, 4, 5, 6, 7}, {1, 2, 3, 4, 5, 6, 7}, {1, 2, 3, 4, 5, 7}}; // Функция выдающая модификацию списка кодов list при выключении лампочек с номерами, заданными списком l UnSet[list_, l_] := Map[Complement[#, l] &, list]; // Функция, определяющая при выключении лампочек со списком лист будет ли однозначность в определении кодов IsBiection[list_, l_] := Length[Union[UnSet[list, l]]] == Length[list]; // Функция, выдающая список списков номеров k выключенных лампочек из списка кодов list при наличии всего n лампочек Biections[list_, n_, k_] := Module[{s, ind}, s = Subsets[Range[1, n], {k}]; Select[Map[If[IsBiection[list, #], #, {}] &, s], Length[#] > 0 &] ]; // Решение NestWhile[{First[#] - 1, Biections[list, n, First[#] - 1]} &, {n - 1, Biections[list, n, n - 1]}, Length[Last[#]] == 0 &] // Ответ для семисегментного индикатора - {2, {{2, 4}, {4, 5}}} Первое число - максимальное количество возможных выключенных лампочек, далее списки с номерами выключенных лампочек.
Комментарии раскрыты, начинаем проверку общности предложенных алгоритмов. Четыре с половиной года назад вот здесь я задавал интересный вопрос. При помощи разработанной Вами программы прошу исследовать различные комбинации начертаний цифр индекса и ответить на вопрос: какое начертание наиболее устойчиво к помехам? Необходимо показать это при помощи строгих вычислений. Дерзайте!
Да, забыл сказать как перенумеровал лампочки - по часовой стрелке от левой верхней (она - единица). Горизонтальная в середине - седьмая.
![[User Picture Icon]](http://l-userpic.livejournal.com/84929242/9858045) |
| From: | stdray |
| Date: |
Ноябрь, 3, 2011 11:43 (UTC) |
|
|
уточнить
|
(Link) |
|
Если номер лампочки Ni ∈ {1..n}, то символ кодируется как набор номеров Ni?
Методы кодирования целиком находятся в Вашем ведении. Как хотите, так и кодируйте.
Для девятисегментных почтовых кодов - нумерация по часовой стрелке начиная с левой верхней (она единица). Внутренние сверху вниз седьмая, восьмая и девятая. Ответ - {5, {{1, 2, 4, 5, 7}, {1, 2, 5, 7, 9}, {1, 4, 5, 6, 7}, {1, 5, 6, 7, 9}}}. Смысл чисел такой же как и в комментарии выше.
Quick and dirty solution. Как принято писать в бизнес-линче, "сделал плохо, зато потратил 8 минут". Головой пока не думал. #! /usr/bin/env python2.7
import itertools
k = []
# Postal code
# - : 5
# |/| : 4,6,0
# - : 7
# |/| : 3,8,1
# - : 2
k.append([1, 1, 1, 1, 1, 1, 0, 0, 0]) # 0
k.append([1, 1, 0, 0, 0, 0, 1, 0, 0]) # 1
k.append([1, 0, 1, 0, 0, 1, 0, 0, 1])
k.append([0, 0, 0, 0, 0, 1, 1, 1, 1])
k.append([1, 1, 0, 0, 1, 0, 0, 1, 0])
k.append([0, 1, 1, 0, 1, 1, 0, 1, 0])
k.append([0, 1, 1, 1, 0, 0, 1, 1, 0])
k.append([0, 0, 0, 1, 0, 1, 1, 0, 0])
k.append([1, 1, 1, 1, 1, 1, 0, 1, 0])
k.append([1, 0, 0, 0, 1, 1, 0, 1, 1]) # 9
leds_count = len(k[0])
leds = range(leds_count)
not_eq = [[i for i in xrange(leds_count) if k[x][i] != k[y][i]] for x in xrange(len(k)) for y in xrange(len(k)/2 + 1) if x != y]
combinations = [list(j) for i in xrange(leds_count) for j in itertools.combinations(leds, i + 1)]
res = [x for x in combinations if not [y for y in not_eq if len([n for n in y if n in x]) == len(y)]]
print reduce(lambda s, x: len(x) > s[0] and (len(x), x) or s, res, (0, []))
Если успею, за выходные придумаю что поприличнее.
Комментарии раскрыты, начинаем проверку общности предложенных алгоритмов. Четыре с половиной года назад вот здесь я задавал интересный вопрос. При помощи разработанной Вами программы прошу исследовать различные комбинации начертаний цифр индекса и ответить на вопрос: какое начертание наиболее устойчиво к помехам? Необходимо показать это при помощи строгих вычислений. Дерзайте!
А сущность, распознающая цифры - она в курсе, какие именно лампочки перегорели, или нет? При разных ответах на этот вопрос разное решение будет у задачи.
Если честно, то этой сущности всё равно. Но, поскольку она должна подсчитать максимальное количество перегоревших лампочек, при котором возможно однозначное распознавание символов алфавита, то она может знать, какие лампочки перегорели. Более того, она может попытаться отобразить на испорченном индикаторе все символы алфавита и посмотреть, что получается.
код: http://pastebin.com/MbtXQgiA результат:
Добро пожаловать в DrRacket, версия 5.2.0.1--2011-11-01(98d8acf/a) [3m]. Язык: racket [выбранный]. '(5 6) 2 '(0 1 2 6) 4 >
Нумерация лампочек слева-направо, сверху-вниз, верхняя лампочка - нулевая, нижняя - последняя.
Комментарии раскрыты, начинаем проверку общности предложенных алгоритмов. Четыре с половиной года назад вот здесь я задавал интересный вопрос. При помощи разработанной Вами программы прошу исследовать различные комбинации начертаний цифр индекса и ответить на вопрос: какое начертание наиболее устойчиво к помехам? Необходимо показать это при помощи строгих вычислений. Дерзайте!
-- -*- coding:utf-8 -*-
import Data.List
import Data.Ord
поискНенужныхЛампочек алфавит@(обрЭлемент:хвост) =
maximumBy (comparing length) $ (map (тестЛампочки алфавит) индексыЛампочек)
where
индексыЛампочек = [0..(length обрЭлемент)-1]
поискНенужныхЛампочек [] = []
тестЛампочки алфавит i = if безНулей $ map метрикаХэмминга варианты
then i:(поискНенужныхЛампочек безЭлементаI)
else []
where
безНулей список = (filter (==0) $ список) == []
варианты = пермумацииЛюбыеДве $ безЭлементаI
безЭлементаI = map (убратьЭлемент i) алфавит
------------------------------------------------------------------------------
-- Утилиты
--
метрикаХэмминга (x,y) = foldr ((+) . xor) 0 $ zip x y
where
xor (a, b) | a == b = 0
xor (a, b) = 1
--
пермумацииЛюбыеДве (эл:хвост) = (параС эл хвост) ++ (пермумацииЛюбыеДве хвост)
where
параС x xs = map (\y -> (x,y)) xs
пермумацииЛюбыеДве [] = []
--
убратьЭлемент i список = начало ++ конец
where
(начало, _:конец) = splitAt i список
------------------------------------------------------------------------------
-- Тестовые наборы
-- =0=
-- | |
-- 1 2
-- | |
-- =3=
-- | |
-- 4 5
-- | |
-- =6=
семисегментныйЦифровой = -- [6,5]
[ [1,1,1,0,1,1,1]
, [0,0,1,0,0,1,0]
, [1,0,1,1,1,0,1]
, [1,0,1,1,0,1,1]
, [0,1,1,1,0,1,0]
, [1,1,0,1,0,1,1]
, [1,1,0,1,1,1,1]
, [1,0,1,0,0,1,0]
, [1,1,1,1,1,1,1]
, [1,1,1,1,0,1,1]]
-- =0=
-- | .|
-- 1 2 3
-- |. |
-- =4=
-- | .|
-- 5 6 7
-- |. |
-- =8=
телеграфныйЦифровой = -- [8,7,6,2,1]
[ [1,1,0,1,0,1,0,1,1]
, [0,0,1,1,0,0,0,1,0]
, [1,0,0,1,0,0,1,0,1]
, [1,0,1,0,1,0,1,0,1]
, [0,1,0,1,1,0,0,1,0]
, [0,1,0,0,1,0,0,1,1]
, [0,0,1,0,1,1,0,1,1]
, [1,0,1,0,0,1,0,0,0]
, [1,1,0,1,1,1,0,1,1]
, [1,1,0,1,1,0,1,0,0]]
-- Для тестов производительности
телеграфныйЦифровой' =
[ [1,1,0,1,0,1,0,1,1,0]
, [0,0,1,1,0,0,0,1,0,0]
, [1,0,0,1,0,0,1,0,1,0]
, [1,0,1,0,1,0,1,0,1,0]
, [0,1,0,1,1,0,0,1,0,0]
, [0,1,0,0,1,0,0,1,1,0]
, [0,0,1,0,1,1,0,1,1,0]
, [1,0,1,0,0,1,0,0,0,0]
, [1,1,0,1,1,1,0,1,1,0]
, [1,1,0,1,1,0,1,0,0,0]]
-- :s +s
-- *Main> поискНенужныхЛампочек семисегментныйЦифровой
-- [6,5]
-- (0.03 secs, 5793152 bytes)
-- *Main> поискНенужныхЛампочек телеграфныйЦифровой
-- [8,7,6,2,1]
-- (2.75 secs, 281484020 bytes)
-- *Main> поискНенужныхЛампочек телеграфныйЦифровой'
-- [9,8,7,6,2,1]
-- (16.58 secs, 1695714620 bytes)
-- *Main>
Ваша программа прекрасна! Комментарии раскрыты, начинаем проверку общности предложенных алгоритмов. Четыре с половиной года назад вот здесь я задавал интересный вопрос. При помощи разработанной Вами программы прошу исследовать различные комбинации начертаний цифр индекса и ответить на вопрос: какое начертание наиболее устойчиво к помехам? Необходимо показать это при помощи строгих вычислений. Дерзайте!
Там, где я обитаю, это называется диагностическими тестами.
Код: http://hpaste.org/53500 Результат: (5,fromList [0,1,2,3,4]) (4,fromList [3,4,5,6])
Он выводит не максимальное, которое нужно убрать, а минимальное, которое нужно оставить. Т.е. для цифровых часов можно убрать 2 лампочки, образующие правый нижний угол. Для почтовых цифр - можно убрать 5 из 9, tests postalDigits говорит, что сделать это можно четырьмя разными способами.
Комментарии раскрыты, начинаем проверку общности предложенных алгоритмов. Четыре с половиной года назад вот здесь я задавал интересный вопрос. При помощи разработанной Вами программы прошу исследовать различные комбинации начертаний цифр индекса и ответить на вопрос: какое начертание наиболее устойчиво к помехам? Необходимо показать это при помощи строгих вычислений. Дерзайте!
![[User Picture Icon]](http://l-userpic.livejournal.com/114301903/14304056) |
| From: | udpn |
| Date: |
Ноябрь, 3, 2011 18:08 (UTC) |
|
|
|
|
(Link) |
|
"Перегорят" это установятся в 0, в 1, или в одно из состояний?
Перегорят — это значит, что если он не горит (а не горит он всегда), то мы не можем сказать, подано на него на самом деле напряжение или нет. То есть перегоревшие лампочки всегда в 0.
![[User Picture Icon]](http://l-userpic.livejournal.com/114301903/14304056) |
| From: | udpn |
| Date: |
Ноябрь, 3, 2011 18:14 (UTC) |
|
|
|
|
(Link) |
|
>> если и перегорят, то не влияют на однозначное распознавание всех символов алфавита. Т.е. если символ s_i будет искажён неким образом, его возможно будет восстановить, зная, какие именно биты перегорели? Или не зная?
Зачем восстанавливать символ? Надо обеспечить распознаваемость символов, то есть заведомое их отличие друг от друга.
User udpn referenced to your post from No title saying: [...] Решал задачку [...]
Благодарю, камрад. Давай ещё.
1. Перебираем все подмножества множества {1,...,n}. Каждое такое множество обозначает номера перегоревших ламночек. 2. Для каждого набора перегоревших ламночек проверяем, можно ли различить между собой символы алфавита, если учитывать, что ламночки из набора не горят. 3. Выбираем самый большой набор из числа отобранных на 2-ом этапе. Получается сложность что-то вроде O(2^n * n^2 * k).
Код - http://pastebin.com/mrQvC6aK Символы алфавита кодируются последовательностями из нулей и единиц. Нумерация лампочек для первого варианта: http://dl.dropbox.com/u/7432711/dig.png Для второго: http://dl.dropbox.com/u/7432711/post.png
Комментарии раскрыты, начинаем проверку общности предложенных алгоритмов. Четыре с половиной года назад вот здесь я задавал интересный вопрос. При помощи разработанной Вами программы прошу исследовать различные комбинации начертаний цифр индекса и ответить на вопрос: какое начертание наиболее устойчиво к помехам? Необходимо показать это при помощи строгих вычислений. Дерзайте!
| From: | morrom |
| Date: |
Ноябрь, 3, 2011 19:36 (UTC) |
|
|
|
|
(Link) |
|
#python 2.6.6
import sys
d={}
n=0
if (len(sys.argv)<3):
f=open(sys.argv[1])
z=f.xreadlines()
else:
z=sys.argv[1:]
for s in z:
ss=s.strip()
if (n==0):
n=len(ss)
if len(ss)<>n:
sys.exit("There is sequence's different lengths. Error.")
i=int(ss,2)
if i in d:
sys.exit("There is duplicate sequences. Error.")
d[i]=ss
maxn=2**n-1
masks={}
for i in xrange(maxn+1):
cd={}
for k in d.keys():
cd[k&i]=1
if len(cd)==len(d):
s=0
for j in xrange(n):
s+=((i<<j)&maxn)>>(n-1)
masks[i]=s
import operator,string
print n-min(masks.values())
print map(lambda x:string.zfill(operator.getslice(x,2,len(x)),n),map(bin,[i for i in masks.keys() if masks[i]==min(masks.values())]))
Комментарии раскрыты, начинаем проверку общности предложенных алгоритмов. Четыре с половиной года назад вот здесь я задавал интересный вопрос. При помощи разработанной Вами программы прошу исследовать различные комбинации начертаний цифр индекса и ответить на вопрос: какое начертание наиболее устойчиво к помехам? Необходимо показать это при помощи строгих вычислений. Дерзайте!
Для данных примеров: У электронных цифр могут перегореть 6 и 7 лампы (нижняя и нижняя правая) У почтовых цифр например 1,2,3,8,9 (считая сверху вниз, слева направо)
http://pastebin.com/L5fTr7DC
Комментарии раскрыты, начинаем проверку общности предложенных алгоритмов. Четыре с половиной года назад вот здесь я задавал интересный вопрос. При помощи разработанной Вами программы прошу исследовать различные комбинации начертаний цифр индекса и ответить на вопрос: какое начертание наиболее устойчиво к помехам? Необходимо показать это при помощи строгих вычислений. Дерзайте!
для индикатора - 2 лампочки для почтовых цифр - 5 "лампочек" можно удалить (4 способа убрать 5 лампочек)
https://gist.github.com/1338554
Комментарии раскрыты, начинаем проверку общности предложенных алгоритмов. Четыре с половиной года назад вот здесь я задавал интересный вопрос. При помощи разработанной Вами программы прошу исследовать различные комбинации начертаний цифр индекса и ответить на вопрос: какое начертание наиболее устойчиво к помехам? Необходимо показать это при помощи строгих вычислений. Дерзайте!
![[User Picture Icon]](http://l-userpic.livejournal.com/41268611/9198054) |
| From: | jtraub |
| Date: |
Ноябрь, 4, 2011 04:51 (UTC) |
|
|
|
|
(Link) |
|
Прош прощения, предыдущий комментарий отправился раньше чем нужно.
Решения: 1. 2 неработающих индикатора (самый нижний и правый нижний) 2. 5 неработающих индикаторов (существует 4 варианта расположения этих пяти индикаторов)
![[User Picture Icon]](http://l-userpic.livejournal.com/41268611/9198054) |
| From: | jtraub |
| Date: |
Ноябрь, 4, 2011 05:43 (UTC) |
|
|
|
|
(Link) |
|
Вот такой вот вопрос пришёл ко мне в голову после написания программы и некоторого осмысления. Знает ли человек (или устройство), который пытается считать цифры с дисплея какие лампочки перегорели? Или же ему известно какие именно индикаторы перегорели и нужно по горящим определить какая цифра отображается?
Вы пытаетесь додумать условие. Не важно, знает или нет. Надо обеспечить различимость символов.
Ваши ответы, приведённые ранее, правильные.
|
|