[Любой язык] Реализация интересной задачи
Компонентный паскаль:
MODULE Gcds;
(* Модуль нахождения наибольших общих делителей *)
IMPORT Log := StdLog;
(* Алгоритм Евклида *)
PROCEDURE Euclid* (x, y: INTEGER): INTEGER;
BEGIN
ASSERT(x > 0); ASSERT(y > 0);
WHILE x # y DO
IF x > y THEN x := x - y ELSE y := y - x END
END;
RETURN x
END Euclid;
PROCEDURE Test* (x, y: INTEGER);
BEGIN
Log.Int(Euclid(x, y; Log.Ln
END Test;
END Gcds.
"Gcds.Test(45, 120)"
15
# let rec gcd n m = if n = 0 then m else if n >= m then gcd (n - m) m else gcd m n ;;
val gcd : int -> int -> int = <fun>
# gcd 45 120 ;;
- : int = 15
Haskell:
PS У тебя нет ASSERT(x>0) и IO тоже нет
gcd 0 a = a
gcd a b = gcd b (a `mod` b)
qsort [] = []
qsort (x:xs) = qsort [x' | x'<-xs, x'<x] ++ [x] ++ qsort [x' | x'<-xs, x'>=x]
Красивый язык.
Надо взботнуть!
а свободная реализация компилятора под свободную ос есть?
а свободная реализация компилятора под свободную ос естьИз популярных реализаций знаю hugs и ghc. Я правда обычно интерпретатором пользовался , но компиляторы там тоже есть.
: gcd begin ?dup while 2dup - abs -rot min repeat ;
45 120 gcd . 15 ok
Короче.
Даже если защищаться от отрицательных значений:
: gcd begin ?dup while over abs over abs - abs -rot min repeat ;
---
VARIABLE 1
BEGIN COMPARISON ?= UNTIL;
EMIT;
язык Форт.
---
...Я работаю антинаучным аферистом...
Я только диалект для ПЭВМ Корвет знаю.
чтобы он понимал ТАКОЕ, или это ты что-то неправильно написал.
---
...Я работаю антинаучным аферистом...
ghc под Линукс пашет отлично, я себе ставил.
Насчет циклов я просто не уверен. Не помню.
---
...Я работаю антинаучным аферистом...
#!/usr/bin/perl -sw
use Quantum::Superpositions;
sub is_prime { return $_[0]==2 || $_[0] % all(2..sqrt($_[0])+1) != 0 }
do{print "$_ - простое число \n" if is_prime($_)} for map {2*$_+1} 1..1000;
еще внизу и факторизация на множители, правда кодировка глючит, руки недойдут исправить
: sqrt 1 1 >r begin 2dup > while r> 2 + dup >r + repeat
2drop r> 1+ 2/ ;
: prime? dup sqrt 1 >r
begin dup 1 > while 2dup mod 0<> r> and >r 1- repeat 2drop r> ;
: .primes 1+ 2 ?do i prime? if i . then loop ;
1000 .primes
Сколько строк кода в твоём "Quantum::Superpositions"?
---
VARIABLE 1
"Primes.OutPrimes(100)"
MODULE Primes;
IMPORT Math, StdLog;
(* Является ли число x простым ? *)
PROCEDURE IsPrime* (x: INTEGER): BOOLEAN;
VAR i, min, max: INTEGER;
BEGIN
ASSERT(x > 1);
min := 2;
max := SHORT(ENTIER(Math.Sqrt(x;
i := min;
WHILE (i <= max) & (x MOD i # 0) DO
INC(i)
END;
RETURN i > max
END IsPrime;
(* Вывод всех простых чисел по n *)
PROCEDURE OutPrimes* (n: INTEGER);
VAR i: INTEGER;
BEGIN
ASSERT(n > 1);
FOR i := 2 TO n DO
IF IsPrime(i) THEN
StdLog.Int(i); StdLog.Tab
END
END;
StdLog.Ln
END OutPrimes;
END Primes.
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
так же классическим можно назвать и обман, заключённый в этом примере:
сортировка не in-place, поэтому называть это qsort несколько неправомерно
Source:
Interface:
MODULE Sort;
PROCEDURE SplitUp (VAR a: ARRAY OF INTEGER; i, j: INTEGER; OUT k: INTEGER);
VAR pivot, t: INTEGER;
BEGIN
ASSERT(j - i > 2);
pivot := a[i + (j - i) DIV 2];
WHILE i < j DO
IF a[i] < pivot THEN
INC(i)
ELSIF a[j - 1] > pivot THEN
DEC(j)
ELSIF a[i] = a[j - 1] THEN
INC(i); DEC(j)
ELSE
t := a[i]; a[i] := a[j - 1]; a[j - 1] := t;
INC(i); DEC(j)
END
END;
ASSERTi = j) OR (i = j + 1;
ASSERT(~(i = j + 1) OR (a[j] = pivot;
k := i
END SplitUp;
PROCEDURE RecSort (VAR a: ARRAY OF INTEGER; i, j: INTEGER);
VAR k, t: INTEGER;
BEGIN
ASSERT(i < j);
IF j - i = 1 THEN
ELSIF j - i = 2 THEN
IF a[i] > a[i + 1] THEN
t := a[i]; a[i] := a[i + 1]; a[i + 1] := t
END
ELSE
SplitUp(a, i, j, k);
ASSERTi < k) & (k < j;
RecSort(a, i, k);
RecSort(a, k, j)
END
END RecSort;
(* Алгоритм "быстрой" сортировки *)
PROCEDURE QuickSort* (VAR a: ARRAY OF INTEGER);
BEGIN
RecSort(a, 0, LEN(a
END QuickSort;
END Sort.
DEFINITION Sort;
PROCEDURE QuickSort (VAR a: ARRAY OF INTEGER);
END Sort.
RecSort(a, i, k);
RecSort(a, k, j)
с таким подходом ему надо O(n) стека, а если делать правильно, то только O(log(n
а как правильно ?
делается только самый короткий из вызовов, а другой разворачивается в цикл
сортировка не in-placeПочему? Точнее, что ты под этим понимаешь? У тебя просто есть свое представление о том как бы ты стал писать интерпретатор Хаскеля, к семантике Хаскеля как таковой это ведь не имеет отношения...
> У тебя просто есть свое представление о том как бы ты стал писать
> интерпретатор Хаскеля, к семантике Хаскеля как таковой это ведь не имеет
> отношения...
Конечно, можно себе представить реализацию, которая сделает это in-place.
Но это не будет свойством программы, это будет свойством реализации.
Данное свойство алгоритма применимо только к реализациях на достаточно низкоуровневых языках. Поэтому я и называю данную реализацию на Haskell обманом.
sieve (x:xs) = [x' | x'<-xs, x' `mod` x > 0]
primes = map head (iterate sieve [2..])
Prelude> primes[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151Библиотечные функции тоже все совсем не сложные
,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,31
3,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,4
91,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,
677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877
,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1
061,1063,1069,1087,1091,1093,{Interrupted!}
PS. Эффективность кстати с перлом не сравнить - это все-таки решето Эратосфена.
head (x:xs) = x
map f xs = [f x | x<-xs]
iterate f x = x : iterate f (f x)
может, не надо ничего разворачивать
в лучшем случае компиляторы только самый последний обрабатывают
Тогда можно будет сравнивать эффективность.
На плоскости размещены кружочки разного диаметра, кружочки не могут друг друга пересекать, или включаться в друг друга.
Кружочки соединены связями.
Связи бывают жесткие и гибкие.
Жесткая связь - не расстягивается, но и не сжимается (железная штанга)
Гибкая связь - не расстягивается, но произвольно сжимается (нитка).
Необходимо спроектировать "модуль", которые выполняет следующие требования:
1. Вывод системы
2. Изменение системы - добавление/удаление кружков и связей с проверкой на корректность
3. Выполнение команд вида - сдвинуть кружок такой-то на такой-то вектор, рассчитав при этом новое положение системы с учетом всех связей.
Дополнительное положение:
Максимально упростить добавление новых видов "кружочков" и новых видов связей.
Усложнения:
1. Есть границы и препятствия - которые не сдвигаются, и мешают движению шариков.
2. Связи полужесткие - имеют длину от a до b
Упрощения:
1. Вместо плоскости - прямая.
2. Точки вместо кружков: кружки не имеют радиуса и могут проходить сквозь друг друга
зы
мне. как постановщику задачи, очень интересно - на сколько сильно можно отделить всю систему от типов связей.
Если приближённое, то можно перейти к дифурам с достаточно гладкой правой частью, и решать их стандартными методами.
Если точное, то скорее всего нужно к символьным вычислениям переходить, и не факт, что получится.
ps
Мне хочется, в основном, посмотреть как будет организована структура программы, а не расчетная часть
> программы, а не расчетная часть
Если сводить к дифурам, то структура простейшая получится.
Набор шариков, и набор связей.
Шарик - это несколько переменных, и функция для вывода состояния.
Связь шарика с другим - для каждой переменной по функции, рассчитывающей усилие связи.
ОсновыПримеры:
Главная идея Brainfuck - манипулирование памятью. Вам выдается 30.000 массив 1 байтовых блоков, хотя на самом деле размер массива зависит от компилятора или интерпретатора, но стандартный размер - 30.000. Внутри этого массива вы можете увеличивать указатель, значение в ячейке и так далее. Для работы, как я уже говорил, используется 8 операторов:
> = увеличение указателя памяти или смещение право на 1 блок
< = уменьшение или смещение влево на 1 блок
+ = увеличение значения в ячейке памяти, на которую ссылается указатель
- = соответственно уменьшение на единиц
[ = аналог цикла while(cur_block_value != 0)
] = если значение в ячейке на которую указывает указатель не равно нулю, то переход на [
, = аналог getchar ввод одного символа
. = аналог putchar вывод одного сивола на кончоль
Вводные правил
Любые символы кроме описанных выше игнорируются
Все значения в памяти устанавливаются на 0 в начале работы программы
Циклов может быть сколько угодно, однако каждая [ должна заканчиваться]
Давайте напишем программу, которая будет уже
выводить нечто в консоль, например любимый всеми нами "Hello world".
Выглядит она так:
>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.
+++++++..+++.[-]>++++++++[<++++>-] <.
>+++++++++++[<++++++++>-]<-.--------.+++
.------.--------.[-]>++++++++[<++++>- ]<+.[-]++++++++++.
[/* bf2c.b
* The omin0us Brainfuck to C interpretor
* omin0us <gmail.com>
*
* NOTE: This was written just before the release of K-1ine * and consequently was rushed to be finished. Currently
* it does not take well to any characters of input besides
* the 8 standard brainfuck operators and newline and EOF.
* So consequently, it will only interpret un-commented code.
* Check my web site <http://dtors.ath.cx> for a later release
* that will probably have support for commented code.
*/]
>+++++[>+++++++<-]>.<<++[>+++++[>+++++++<-]<-]>>.+++++.<++[>-----<-]>-.<++
[>++++<-]>+.<++[>++++<-]>+.[>+>+>+<<<-]>>>[<<<+>>>-]<<<<<++[>+++[>---<-]<-
]>>+.+.<+++++++[>----------<-]>+.<++++[>+++++++<-]>.>.-------.-----.<<++[>
>+++++<<-]>>.+.----------------.<<++[>-------<-]>.>++++.<<++[>++++++++<-]>
.<++++++++++[>>>-----------<<<-]>>>+++.<-----.+++++.-------.<<++[>>+++++++
+<<-]>>+.<<+++[>----------<-]>.<++[>>--------<<-]>>-.------.<<++[>++++++++
<-]>+++.---....>++.<----.--.<++[>>+++++++++<<-]>>+.<<++[>+++++++++<-]>+.<+
+[>>-------<<-]>>-.<--.>>.<<<+++[>>++++<<-]>>.<<+++[>>----<<-]>>.++++++++.
+++++.<<++[>---------<-]>-.+.>>.<<<++[>>+++++++<<-]>>-.>.>>>[-]>>[-]<+[<<[
-],[>>>>>>>>>>>>>+>+<<<<<<<<<<<<<<-]>>>>>>>>>>>>>>[<<<<<<<<<<<<<<+>>>>>>>>
>>>>>>-]<<+>[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-[-
[-[-[-[-[-[-[-[-[-[-[-[<->[-]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]<[
<<<<<<<<<<<<[-]>>>>>>>>>>>>[-]]<<<<<<<<<<<<[<+++++[>---------<-]>++[>]>>[>
+++++[>+++++++++<-]>--..-.<+++++++[>++++++++++<-]>.<+++++++++++[>-----<-]>
++.<<<<<<.>>>>>>[-]<]<<<[-[>]>>[>++++++[>+++[>++++++<-]<-]>>++++++.-------
------.----.+++.<++++++[>----------<-]>.++++++++.----.<++++[>+++++++++++++
++++<-]>.<++++[>-----------------<-]>.+++++.--------.<++[>+++++++++<-]>.[-
]<<<<<<<.>>>>>]<<<[-[>]>>[>+++++[>+++++++++<-]>..---.<+++++++[>++++++++++<
-]>.<+++++++++++[>-----<-]>++.<<<<<<.>>>>>>[-]<]<<<[-[>]>>[>+++[>++++[>+++
+++++++<-]<-]>>-.-----.---------.<++[>++++++<-]>-.<+++[>-----<-]>.<++++++[
>----------<-]>-.<+++[>+++<-]>.-----.<++++[>+++++++++++++++++<-]>.<++++[>-
----------------<-]>.+++++.--------.<++[>+++++++++<-]>.[-]<<<<<<<.>>>>>]<<
<[<+++[>-----<-]>+[>]>>[>+++++[>+++++++++<-]>..<+++++++[>++++++++++<-]>---
.<+++++[>----------<-]>---.<<<<<<.>>>>>>[-]<]<<<[--[>]>>[>+++++[>+++++++++
<-]>--..<+++++++[>++++++++++<-]>-.<+++++[>----------<-]>---.[-]<<<<<<.>>>>
>]<<<[<+++[>----------<-]>+[>]>>[>+++[>++++[>++++++++++<-]<-]>>-.<+++[>---
--<-]>.+.+++.-------.<++++++[>----------<-]>-.++.<+++++++[>++++++++++<-]>.
<+++++++[>----------<-]>-.<++++++++[>++++++++++<-]>++.[-]<<<<<<<.>>>>>]<<<
[--[>]>>[>+++++[>+++++[>+++++<-]<-]>>.[-]<<<<<<<.>>>>>]<<<[<++++++++++[>--
--------------<-]>--[>]>>[<<<<[-]]]]]]]]]]]>>]<++[>+++++[>++++++++++<-]<-]
>>+.<+++[>++++++<-]>+.<+++[>-----<-]>.+++++++++++.<+++++++[>----------<-]>
------.++++++++.-------.<+++[>++++++<-]>.<++++++[>+++++++++++<-]>.<+++++++
+++.
Что будет, если функция связи будет негладкая, разрывная или дискретная?
Это нужно делать для добавления нового вида связи.
Если захочется ещё и погрешность оценивать, то надо ещё подумать, и либо самому выводить оценки для каждого типа связи, или программу заставить, опять же введя символьные вычисления.
Мне нравится пример (наконец-то не чистая математика, где Java явно не чемпион но хотелось бы больше конкретики.
1) телепортировать кружок
2) двигать его по прямой
3) двигать по кривой
Кроме того, решение в данном случае не единственное даже без учета поворотов.
> Кроме того, решение в данном случае не единственное даже без учета поворотов
Попробовать приблизиться к реалу.
нет.
> Мне нравится пример (наконец-то не чистая математика, где Java явно не чемпион но хотелось бы больше конкретики.
Попробуй доопределить сам
Оставить комментарий
enochka1145
Чего бы хотелось мне, так это посмотреть, как различные задачи (а не только "Hello, world!") реализуются на различных языках программирования. Если есть желание показать различные языки в деле, предлагайте свои задачи. Под этим ником - - я буду всячески нахваливать именно Java. Так что если у кого есть желание поопускать Java или Java-программистов - вам особое приглашение.