Любопытные программы

Описание: Разработка и отладка приложений. Упор на 3D-графику.

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3631
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#1 dyvniy » Чт, 29 октября 2015, 17:59:27

Квайны - программы, выводящие на экран свой исходный код.

python

Код: Выделить всё

q="'";s='q="";s=;print(s[:3]+q+s[3:7]+q+s+q+s[7:])';print(s[:3]+q+s[3:7]+q+s+q+s[7:]) 

C

Код: Выделить всё

#include <stdio.h>
int main(){const char *s="#include <stdio.h>int main(){const char *s=;printf(%.18s%c%.25s%c%s%c%.8s%c%.33s%c%s,s,10,s+18,34,s,34,s+43,34,s+51,34,s+84);return 0;}";printf("%.18s%c%.25s%c%s%c%.8s%c%.33s%c%s",s,10,s+18,34,s,34,s+43,34,s+51,34,s+84);return 0;}
 

JavaScript (используя хак)

Код: Выделить всё

(function quine() {
    console.log("(" + quine.toString() + "())");
}()) 


Текст
http://habrahabr.ru/post/128191/
Спойлер
Как писать квайны
Ненормальное программирование*
Введение

Многие программисты считают написание квайнов (программ, выводящих свой исходный код) непосильной задачей. И действительно — все эти цепные квайны и квайны различного порядка, при взгляде на которые можно потеряться в, казалось бы, бессмысленном наборе символов…

Однако, на самом деле, написать квайн на каком-либо языке не так сложно, как кажется. Сейчас я расскажу, как сделать это на различных языках программирования. Более того, мы не будем использовать «хаки» интерпретеруемых языков вроде операции вывода исходного кода и функций типа eval и напишем квайны на интерпретируемых и компилируемых языках.

Теория

Попробуем написать квайн. Для этого возьмём инструкцию языка для вывода и передадим ей как параметр код программы. Однако, в коде мы снова используем этот же код и так далее — возникает бесконечная рекурсия. Но что можно сделать для того, чтобы не передавать строковую константу? Решение — поместить строку (копию части кода) в переменную. Для удобства назовём такую строку s-строкой, а переменную с этой строкой — s-переменной. Чтобы и в s-переменной не было рекурсии, мы просто исключим из неё фрагмент со значением этой самой переменной. То есть, выглядеть это будет примерно так:

C:
char s[]="char s[]=;";

Примечание. Как в этом фрагменте, так и в квайнах, которые получатся в итоге, для простоты мы не будем соблюдать правила форматирования кода. Тем не менее, их соблюдение вы сможете без труда добавить самостоятельно после прочтения статьи.

Далее, при выводе, мы подставим значение s-строки в её же определение в коде (в примере выше — перед тремя последними символами). Здесь же возникает ещё несколько проблем. Первая проблема — при подставлении в s-строке нельзя использовать символы, которые поведут себя в коде не так, как надо. Например, мы не можем так просто вставить кавычку — ведь вместо того, чтобы стать частью s-строки, она завершит её определение и выводимый код не будет совпадать с исходным, являясь некорректным вообще.

Экранирование применить здесь достаточно сложно — символ экранирования надо тоже экранировать и т.д.. Гораздо проще, например, использовать другой вариант кавычек — так, во многих интерпретируемых языках разрешено использование как одинарных, так и двойных кавычек для задания строки, а отличие состоит в том, что можно без проблем использовать одну кавычку в константе, если она ограничивается другими. То есть, код '"' создаст односимвольную строку с двойной кавычкой, а код "'" — с одиночной. Если использовать этот вариант, удобно задать в начале переменную с какой-либо кавычкой, а затем использовать её при выводе.

Но и этот вариант не универсален: в Си, к примеру, есть лишь один вариант кавычек. Тогда можно использовать другой способ — задавать кавычку кодом символа, печатая символ с таким кодом при выводе.

Следующая проблема — вставка другой строки (или символа с каким-либо кодом) в вывод s-строки. Решение здесь очевидно — брать подстроку s-строки специальной функцией, выводить её, далее выводить то, что надо вставить, затем выводить другую подстроку s-строки. Может показаться, что в Си взятие подстроки для вывода потребует немало кода. Тут нам на помощь придёт мощь функции printf. Так, например, вот варианты кода для различных языков, печатающего часть строки s со второго символа (считая с единицы) по четвёртый включительно:

Python:
print(s[1:4])

Ruby:
print s[1..3]

Perl:
print substr(s,1,2)

C:
printf("%.2s",s+1);

Обычно методы взятия подстроки могут также брать её остаток до конца. Например, напечатаем строку s со второго символа до конца строки (то есть, всю строку кроме первого символа):

Python:
print(s[1:])

Ruby:
print s[1..-1]

Perl:
print substr(s,1)

C:
printf("%s",s+1);

Если такой возможности нет, придётся на место параметра с длиной подстроки поставить заглушку типа «XX», а затем в конце посчитать символы до конца и подставить их вместо «XX» в коде и в s-строке, не изменяя длины различных частей кода. Например, если в длине окажется одна цифра, целесообразно подставить вместо первого икса пробел, ведь, если его удалить, длины частей s-строки изменятся и их придётся пересчитывать.

Интерпретируемые языки

Итак, начнём писать квайны, собрав все суждения выше. На Python я написал такой квайн (работает и на 3.x):
q="'";s='q="";s=;print(s[:3]+q+s[3:7]+q+s+q+s[7:])';print(s[:3]+q+s[3:7]+q+s+q+s[7:])

Здесь переменная q используется как переменная, где хранится одинарная кавычка, далее идёт определение s-переменной со всем кодом, кроме самой s-строки. После этого идёт вывод s-переменной со следующими вставками:
1). Одинарная кавычка как значение переменной q;
2). Одинарная кавычка как начало определения s-строки;
3). Сама s-строка (да-да, s-строка вставляется внутри s-строки);
4). Одинарная кавычка как конец определения s-строки.

Примечание. При написании квайнов по данному методу не забывайте копировать все изменения в коде в копию кода в s-строке.

С минимальными изменениями можно получить квайн только для Python 2.x:
q="'";s='q="";s=;print s[:3]+q+s[3:7]+q+s+q+s[7:]';print s[:3]+q+s[3:7]+q+s+q+s[7:]

Абсолютно аналогичны и квайны на других языках, где мы изменяем лишь некоторые синтаксические особенности:

Ruby:
q="'";s='q="";s=;print s[0..2]+q+s[3..6]+q+s+q+s[7..-1]';print s[0..2]+q+s[3..6]+q+s+q+s[7..-1]

Perl:
$q="'";$s='$q="";$s=;print substr($s,0,4).$q.substr($s,4,5).$q.$s.$q.substr($s,9)';print substr($s,0,4).$q.substr($s,4,5).$q.$s.$q.substr($s,9)

PHP:
<?$q="'";$s='<?$q="";$s=;print substr($s,0,6).$q.substr($s,6,5).$q.$s.$q.substr($s,11);';print substr($s,0,6).$q.substr($s,6,5).$q.$s.$q.substr($s,11);

Компилируемые языки.

Написание квайна на C оказалось чуть более трудной задачей. Здесь я активно использовал коды символов: двойной кавычки — 34, и перевода строки — 13 (он понадобился, чтобы отделить директиву компилятора для включения stdio.h), а также интересный способ взятия подстроки с помощью printf, уже описанный выше.

А вот и сам квайн:
#include <stdio.h>
int main(){const char *s="#include <stdio.h>int main(){const char *s=;printf(%.18s%c%.25s%c%s%c%.8s%c%.33s%c%s,s,10,s+18,34,s,34,s+43,34,s+51,34,s+84);return 0;}";printf("%.18s%c%.25s%c%s%c%.8s%c%.33s%c%s",s,10,s+18,34,s,34,s+43,34,s+51,34,s+84);return 0;}

Заключение

Вот и всё. Я написал квайны на большинстве языков, интерпретаторы и компиляторы которых обнаружил на своём компьютере. Думаю, теперь вы и сами напишете подобную программу на своём любимом языке программирования, если я не упомянул его здесь. В качестве упражнения вы также можете написать квайн на таких языках, как Java, C#, Haskell или Pascal. Не бойтесь трудностей — достаточно попробовать, и всё получится!
квайн, ненормальное программирование, python, ruby, perl, php, си, c
+76

8527

98


Александр Борзунов @hx0 карма130,0 рейтинг0,0
Похожие публикации

Учебник программирования «Hello Ruby» для детей собрал $288 000 на Kickstarter (32)
Публикуем веб приложения Ruby, Python, Node.js, Perl и Java в Azure Cloud Services (4)
Шаблон программирования «Текучий интерфейс» в PHP. Свежий взгляд (67)
Занимательное функциональное программирование в Ruby (20)
Online — обучение программированию на Ruby без хабраэффекта (11)
Комментарии (55)

–7 terrance11 сентября 2011 в 13:48#
Квайн на Basic:

LIST
+7 AbnormalHead11 сентября 2011 в 20:09#↵↑
Вы, по-видимому, не читали данную в статье ссылку. Там прямо в первом абзаце сказано, что LIST — является грязным хаком.
0 sova12 сентября 2011 в 23:55#↵↑
некоторым людям нравятся грязные хаки
+4 sst23911 сентября 2011 в 13:59#
HQ9+
Q
+8 silencer11 сентября 2011 в 14:11#↵↑
Можно еще на 1 байт сократить размер программы. Тогда будет работать на большем количестве языков, а не только на HQ9+. :-)
+5 AbnormalHead11 сентября 2011 в 21:57#↵↑
Вырождение программы до нулевого размера также не является квайном
0 silencer12 сентября 2011 в 07:41#↵↑
Только после этого случая: www0.us.ioccc.org/1994/smr.hint

In the future, the contest rules will specify a minimum size that is one character larger than this entry, forever eliminating this sort of program from contest. After all, how many variations can one make on this entry? :-)
–2 vladoos11 сентября 2011 в 14:00#
хм, а к чему это? Я понимаю так — если бы выходные данные можно было подать в качестве входных данных, модифицировать, перекомпилировать, а за тем снова использовать в качестве выходного параметра для самой себя было намного интереснее. Избавляться от рекурсии тут совершенно зря. Рекурсия нужна, встает только вопрос что лучше использовать в качестве выходной стоки для разбора, исходный язык программирования, бинарную строку или нечто промежуточное, типа байт кода.
0 ilyaplot11 сентября 2011 в 14:06#
Все таки, как правильно, квайн или куайн
+1 ShpuntiK11 сентября 2011 в 14:24#↵↑
квайн
0 Xlab11 сентября 2011 в 14:48#↵↑
квайн
0 hx011 сентября 2011 в 15:13#↵↑
Оба варианта допустимы.

> Куайн, квайн (англ. quine) — компьютерная программа, которая выдаёт на выходе точную копию своего исходного текста. Следует заметить, что программы, использующие внешние данные, куайнами не считаются; то есть исключается прочтение текста программы из файла, ввод его с клавиатуры и так далее. Кроме того, не считается куайном «программа», не содержащая вообще никакого кода (вырожденный случай). (с) Wikipedia
+16 mariofag11 сентября 2011 в 15:18#↵↑
Кавайн ^_^
+1 vicnaum11 сентября 2011 в 19:12#↵↑
кўайн :)
+1 Ostrovski11 сентября 2011 в 14:16#
Попробуем написать квайн. Для этого возьмём инструкцию языка для вывода и передадим ей как параметр код программы. Однако в коде мы снова используем этот же код и так далее — возникает бесконечная рекурсия. Но что можно сделать для того, чтобы не передавать строковую константу? Решение — поместить строку (копию части кода) в переменную. Для удобства назовём такую строку s-строкой, а переменную с этой строкой — s-переменной. Чтобы и в s-переменной не было рекурсии, мы просто исключим из неё фрагмент задания этой самой переменной. То есть, выглядит это примерно так:

C:
const char *s=«const char *s=;»;


Вы решили взорвать мой мозг, чтобы в понедельник я на работу не вышел? ) Интересная ПЕРЕМЕНная с модификатором const, причем не содержащая «фрагмент задания этой самой переменной» «const char *s=;»
+1 hx011 сентября 2011 в 15:22#↵↑
Поправил)
+1 Ostrovski11 сентября 2011 в 15:34#↵↑
Ухты, спасибо =) В принципе мысль и так была понятна, просто спросонья решил побурчать…
–2 sundoser11 сентября 2011 в 14:47#
Наверно самый простой квайн это в бинарнике (если считать что бинарник это самый машинный язык), открыть свой исполняемый на чтение и вывести в хексах или в бине.
0 hx011 сентября 2011 в 15:14#↵↑
> Куайн, квайн (англ. quine) — компьютерная программа (частный случай метапрограммирования), которая выдаёт на выходе точную копию своего исходного текста. Следует заметить, что программы, использующие внешние данные, куайнами не считаются; то есть исключается прочтение текста программы из файла, ввод его с клавиатуры и так далее. Кроме того, не считается куайном «программа», не содержащая вообще никакого кода (вырожденный случай).
+8 argos11 сентября 2011 в 14:54#
Хороший квайн на питоне нашёл. Сохранить в файл fail.py и запустить:

File «fail.py», line 1
File «fail.py», line 1
^
IndentationError: unexpected indent

+2 argos11 сентября 2011 в 14:59#↵↑
ай, тег code не работает, форматирование съехало.
Вообщем ссылка на оригинал: www.reddit.com/r/Python/comments/k9857/xx010_prin ... formatchr34x/c2ijqff?context=1
0 eugzol11 сентября 2011 в 23:51#↵↑
очень клёво :)
0 koorchik11 сентября 2011 в 15:06#
Квайн на Perl:
seek( DATA, 0, 0 );
print ;
__DATA__
–1 koorchik11 сентября 2011 в 15:07#↵↑
Вернее
seek( DATA, 0, 0 );
print <DATA>;
__DATA__;
+2 silencer11 сентября 2011 в 18:44#↵↑
Еще проще: open 0; print <0>;
0 valzevul11 сентября 2011 в 15:31#
Более того, мы не будем использовать «хаки» интерпретеруемых языков вроде операции вывода исходного кода и функций типа eval

Простите, а можно поподробнее про вывод кода программы с помощью операции вывода кода программы или функции eval()? На питоне, например.
Даже не подозревал о таком.
0 hx011 сентября 2011 в 16:18#↵↑
Конечно, сразу код так не вывести, но часто это может значительно упростить задачу: только лишь присвоили переменной код, вывели код и исполнили код.
0 valzevul11 сентября 2011 в 16:19#↵↑
Понятно. спасибо.
+3 azproduction11 сентября 2011 в 16:03#
JavaScript (Mozilla JaggerMonkey) с выводом в консоль:
(function quine() {
console.log("(" + quine.toString() + "())");
}())

Т.к. движков JavaScript много, то универсальный квайн написать нельзя
+1 naryl12 сентября 2011 в 20:45#↵↑
Думаю это тоже читерство, но вот более переносимая версия, правда для другого языка. :] Если сделать (setf *print-pretty* nil), то любая реализация должна вывести одинаково:

(DEFUN QUINE NIL (WRITE (APPEND (QUOTE (DEFUN QUINE NIL)) (CDDR (THIRD (FUNCTION-LAMBDA-EXPRESSION (FUNCTION QUINE)))))) (WRITE (QUOTE (QUINE))))(QUINE)

Вот версия с pretty print'ом, но её разные реализации могут с отличиями выводить:

(DEFUN QUINE ()
(WRITE
(APPEND '(DEFUN QUINE ())
(CDDR (THIRD (FUNCTION-LAMBDA-EXPRESSION #'QUINE)))))
(WRITE '(QUINE)))(QUINE)
0 0xy 2 августа 2013 в 10:56#↵↑
Можно короче

(function () {
console.log("(" + arguments.calee.toString() + "())");
}())
+1 naryl11 сентября 2011 в 16:25#
Без строк. :P

(=> — это вывод системы)

(progn (defparameter s '(progn (defparameter s) (write (list (first s) (append (second s) (list `',s)) (third s))))) (write (list (first s) (append (second s) (list `',s)) (third s))))

=> (progn (defparameter s '(progn (defparameter s) (write (list (first s) (append (second s) (list `',s)) (third s))))) (write (list (first s) (append (second s) (list `',s)) (third s))))

(eval *) ; Попробуем выполнить результат

=> (progn (defparameter s '(progn (defparameter s) (write (list (first s) (append (second s) (list `',s)) (third s))))) (write (list (first s) (append (second s) (list `',s)) (third s))))

(equalp ** ++) ; равна ли позапрошлая команда тому что она выводит

=> t ; true :)
–1 Amper11 сентября 2011 в 19:08#
Python-читерство =))

print(open(__file__).read())
+2 xonix11 сентября 2011 в 22:21#↵↑
#!/bin/cat
0 powder9611 сентября 2011 в 22:35#↵↑
Штуки как <?php echo file_get_contents(__FILE__); ?> квайнами не сичтаются: «исключается прочтение текста программы из файла» — из википедии.
0 hx011 сентября 2011 в 22:40#↵↑
Мне просто надоело уже википедию копировать, ведь не первый раз уже.
0 Duti_Fruti11 сентября 2011 в 22:49#
Какое практическое применение квайнов? Тема интересная, но пока не могу понять где в практике можно использовать.
+2 naryl11 сентября 2011 в 23:00#↵↑
нигде
+1 naryl12 сентября 2011 в 19:44#↵↑
По оценкам за мои два комментария в этом топике можно подумать что капитанство оценивается на Хабре выше чем написание квайнов.
–1 hx012 сентября 2011 в 19:54#↵↑
Хабр такой хабр.
+2 mekegi11 сентября 2011 в 23:06#↵↑
Также как и решение задач, головоломок ребусов и тд. в реальной жизни мало где находят применения, однако ж действия сии заставляют мозги работать и держат их в тонусе. Так что польза от этого все же есть.
–2 mardy_bum12 сентября 2011 в 02:49#↵↑
На собеседовании могут спросить
0 runcore12 сентября 2011 в 05:43#
<?php printf($a='<?php printf($a=%c%s%c,39,$a,39);',39,$a,39);
0 Mrrl22 сентября 2011 в 12:38#↵↑
А порядок вычисления параметров фукции гарантируется? Точно ли присваивание выполнится до использования $a в качестве третьего параметра? И не надо ли закрыть скобку?
0 runcore22 сентября 2011 в 12:48#↵↑
гарантируется. точно. какую?
0 Mrrl22 сентября 2011 в 13:02#↵↑
Парную к <?php? Или она и не должна закрываться?
0 3vi1_0n312 сентября 2011 в 09:06#
На windows cmd считается за квайн?
<---cut--->
@type %0
<---cut--->
Или это тоже грязный хак?
0 AbnormalHead12 сентября 2011 в 22:39#↵↑
Скорей всего хак. Т.к. явно читает код собственной программы.
0 afiskon12 сентября 2011 в 09:24#
main = putStr (s ++ show s) where s = «main = putStr (s ++ show s) where s = „
+1 ta6aku12 сентября 2011 в 11:39#
чисто для отчетности

Java

package ru.fso.test;public class Quine {public static void main(String[] args) {char sq = '"';String cf = "%c";String sf = "%s";String s = "package ru.fso.test;public class Quine {public static void main(String[] args) {char sq = '%c';String cf = %c%s%c;String sf = %c%s%c;String s = %c%s%c;System.out.println(String.format(s,sq,sq,cf,sq,sq,sf,sq,sq,s,sq));}}";System.out.println(String.format(s,sq,sq,cf,sq,sq,sf,sq,sq,s,sq));}}
0 talmuth12 сентября 2011 в 20:58#
А квайн не лиспе:

T

?
0 naryl12 сентября 2011 в 22:30#↵↑
А я ещё стопицот таких «квайнов» на лиспе знаю:

«a»
«aa»
«aaa»
«100500»
и т.д.

Впрочем, они и в хаскеле, и в руби, и в питоне работают.

Квайн должен явно распечатывать свой исходный код. Если выполнить ваш квайн, сохранив в файл, то ничего не выведется.
0 MadRogue19 сентября 2011 в 14:01#
<?php
header("Content-type: text/plain; charset=UTF-8");
function hexToStr($hex)
{
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2)
{
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
$param = "|3c3f706870200d0a202020206865616465722822436f6e74656e742d747970653a20746578742f706c61696e3b20636861727365743d5554462d3822293b0d0a2020202066756e6374696f6e20686578546f5374722824686578290d0a202020207b0d0a202020202020202024737472696e673d27273b0d0a2020202020202020666f72202824693d303b202469203c207374726c656e2824686578292d313b2024692b3d32290d0a20202020202020207b0d0a20202020202020202020202024737472696e67202e3d206368722868657864656328246865785b24695d2e246865785b24692b315d29293b0d0a20202020202020207d0d0a202020202020202072657475726e2024737472696e673b0d0a202020207d0d0a2020202024706172616d203d20227c223b0d0a20202020246465636f646564203d20686578546f537472287375627374722824706172616d2c3129293b0d0a20202020666f72202824693d303b202469203c207374726c656e28246465636f646564293b202b2b2469290d0a202020207b0d0a096966286f726428246465636f6465645b24695d293d3d313234297b0d0a2020202020202020202020206563686f2024706172616d3b0d0a20202020202020207d656c73657b0d0a2020202020202020202020206563686f20246465636f6465645b24695d3b0d0a20202020202020207d0d0a202020207d0d0a3f3e";
$decoded = hexToStr(substr($param,1));
for ($i=0; $i < strlen($decoded); ++$i)
{
if(ord($decoded[$i])==124){
echo $param;
}else{
echo $decoded[$i];
}
}
?>
0 MadRogue19 сентября 2011 в 14:05#↵↑
Код, печатающий сам себя. Может быть не самый короткий, но подобный способ работает на всех или почти всех языках программирования.

<?php
header("Content-type: text/plain; charset=UTF-8");
function hexToStr($hex)
{
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2)
{
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
$param = "|3c3f706870200d0a202020206865616465722822436f6e74656e742d747970653a20746578742f706c61696e3b20636861727365743d5554462d3822293b0d0a2020202066756e6374696f6e20686578546f5374722824686578290d0a202020207b0d0a202020202020202024737472696e673d27273b0d0a2020202020202020666f72202824693d303b202469203c207374726c656e2824686578292d313b2024692b3d32290d0a20202020202020207b0d0a20202020202020202020202024737472696e67202e3d206368722868657864656328246865785b24695d2e246865785b24692b315d29293b0d0a20202020202020207d0d0a202020202020202072657475726e2024737472696e673b0d0a202020207d0d0a2020202024706172616d203d20227c223b0d0a20202020246465636f646564203d20686578546f537472287375627374722824706172616d2c3129293b0d0a20202020666f72202824693d303b202469203c207374726c656e28246465636f646564293b202b2b2469290d0a202020207b0d0a096966286f726428246465636f6465645b24695d293d3d313234297b0d0a2020202020202020202020206563686f2024706172616d3b0d0a20202020202020207d656c73657b0d0a2020202020202020202020206563686f20246465636f6465645b24695d3b0d0a20202020202020207d0d0a202020207d0d0a3f3e";
$decoded = hexToStr(substr($param,1));
for ($i=0; $i < strlen($decoded); ++$i)
{
if(ord($decoded[$i])==124){
echo $param;
}else{
echo $decoded[$i];
}
}
?>
+1 Mrrl22 сентября 2011 в 12:34#
На базовом С не требуется объявления прототипа функции (если она возвращает int). Поэтому stdio.h подключать не обязательно. И код можно сократить:

main(){char*s=«main(){char*s=%c%s%c;printf(s,34,s,34);}»;printf(s,34,s,34);}

76 символов.
Изображение

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3631
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 5 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#2 dyvniy » Пт, 1 сентября 2017, 15:57:24

В скайпе можно интервью проводить)
https://interviews.skype.com
Изображение


Название раздела: Программирование (под Desktop и Android)
Описание: Разработка и отладка приложений. Упор на 3D-графику.

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения
:) ;) :hihi: :P :hah: :haha: :angel: :( :st: :_( :cool: 8-| :beee: :ham: :rrr: :grr: :* :secret: :stupid: :music: Ещё смайлики…
   

Вернуться в «Программирование (под Desktop и Android)»

Кто сейчас на форуме (по активности за 15 минут)

Сейчас этот раздел просматривают: 1 гость