Перейти к публикации
Форум - ComputerCraft
Totoro

Конкурс Парсинг изображений в ASCII (любой ЯП)

Рекомендованные сообщения

ldgmZdK.png

 

У нас тут новый мини-конкурс. Ну вы наверное знаете.

(Если не знаете - забегите к Фингеру в блог, почитайте, и присоединяйтесь к веселью.  :D )

 

Смысл такой, в двух словах: есть картинка, надо её распарсить и нарисовать ascii-символами в консоль.

Можно юзать абсолютно любой язык программирования.

При этом надо постараться сделать свой код как можно короче. Ну, в общем читайте точные правила у Фингера.

 

В эту тему можно постить свои решения. Только оформляйте исходники в теги "code".

Обсуждаем в чате или в IRC, чтобы не захламлять тему.

 

 

На задачку даётся неделя времени. Но она лёгкая, так что я посидел вечером и написал, для почину, свой вариант.

 

Язык: Scala 2.11.8 (Java >= 7)

Вес (по минимуму): 620 байт

Полный код (в читабельном виде):

import java.nio.file.{Files, Paths}
import java.nio.{ByteBuffer, ByteOrder}

object BumpGold extends App {
  def word(array: Array[Byte], offset: Int) =
    ByteBuffer.wrap(array, offset, 4).order(ByteOrder.LITTLE_ENDIAN).getInt

  val array = Files.readAllBytes(Paths.get(args(0)))
  val offset = word(array, 10)
  val width = word(array, 18)

  println(
    (for(i <- offset until array.length by width*4)
       yield array.slice(i, i+width*4).map(_ & 0xFF).grouped(4)
         .foldLeft("")((a, b) => a + ((b(0), b(1), b(2), b(3)) match {
           case (_, _, _, a) if a <= 0 => " "
           case (r, g, b, _) if r < 51 && g < 51 && b < 51 => "█"
           case (r, g, b, _) if r < 102 && g < 102 && b < 102 => "▓"
           case (r, g, b, _) if r < 154 && g < 154 && b < 154 => "▒"
           case (r, g, b, _) if r < 205 && g < 205 && b < 205 => "░"
           case _ => "·"
         }))
    ).reverse.mkString("\n")
  )
}

Прогон с тестовой картинкой (16 на 16):

 

0yvU5Cz.png

 

Ещё одна картинка: http://i.imgur.com/Hp0EBs7.png

Минифицированный код: http://pastebin.com/27fntVdz

 

 

Кто рискнёт побить мой рекорд?  :D

Изменено пользователем Alex
  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я рискну :P

320 байт, Python 3.5

 

#coding=utf-8
import sys
a=open(sys.argv[1],'rb').read()
f=lambda x:int.from_bytes(x,'little')
o,s,w,h=[f(a[x:x+4])for x in range(10,26,4)]
d=a[o:]
print('\n'.join(''.join('█▓▒░ ·'[int((max(d[x],d[x+1],d[x+2])+1)//51.2*d[x+3]/255)if d[x+3]>0 else 5]for x in range(y*w*4,(y+1)*w*4,4))for y in range(h-1,-1,-1)))

По строчкам, потому что и пеернос строки, и ; занимают одинаковое число байт: один.

Файл задавать аргументом:

 

python3.5 ./reader.py ~/img/16x16.bmp

Вот что получается:

wUP8PxI.png

  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

162 байта. Pyth master (Unsafe mode - вставки на Python).  :Р

DlNR$int.from_bytes(N[1:4],'little')$Jw=Zg$open(J,'rb').read()$18=JlZ=ZgZ5=NlZ=ZgZ120FdUNFTUJ=b:Z1 5=+k@"|=#' ."?>@b4 0/h++@b1@b2@b3 154 5=ZgZ5)=+k"\n")j_c<1k"\n"

Передаем путь к файлу в stdin, получаем картинку. Отмечу еще что пока оно отображает пиксели другими символами, проблема была в том что не получилось заставить Pyth работать с UTF-8. (Так что я вряд-ли победю, решать вам).

Установка:

$ git clone https://github.com/isaacg1/pyth.git <path to pyth>
$ alias pyth="python3 <path to pyth>/pyth.py"

Запуск:

$ echo <path to image> | pyth bump.pyth

Скрины:

8bfb2440a4854ad3a44ac3862d441862.png

 

 

 

 

691daef024c346adb078ca68b6ccde09.png

 

c6a5ed8901514abe8a9308d5d43563a8.png

 

 

 

Не забывайте что тут вместо юникод символов которые нужно было использовать используются ASCII символы, так что победы мне не видать.

Изменено пользователем LeshaInc
  • Like 5

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Я наверное тоже оставлю это здесь. Мой подход немного не честный, но он не противоречит правилам152 байта Python3.5

 

Код программы

import sys,socket as o
s=o.socket()
a=sys.argv
s.connect((a[2], 9090))
s.send(a[1].encode())
d=1
while d:
    d=s.recv(65534)
    sys.stdout.write(d.decode())

Одной строкой

"import sys,socket as o\ns=o.socket()\na=sys.argv\ns.connect((a[2],9090))\ns.send(a[1].encode())\nd=1\nwhile d:\n\td=s.recv(65534)\n\tsys.stdout.write(d.decode())\n"

Запуск программы

python <file_name.py> <image_name.bmp> <server_ip>

Испытания

 

xRb64IQ.png

 

eDQZsE2.png

 

xdvKy9I.png

 

Ps. Позже попробую выложить минимизированный алгоритм прямой расшифровки.

  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

@@Seryoga, не честно так, тут люди целый день новый язык учили, а ты взял вот так просто и обогнал

Изменено пользователем LeshaInc
  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

LeshaInc, +1

 

Нео, для кого в шапке написано - "Обсуждаем в чате или в IRC, чтобы не захламлять тему." ?

Ты мог вместо этого своего "плюс один" - просто лайк Лёхе поставить. Репа бы апнулась и тема бы не захламлялась.

Изменено пользователем Totoro

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

237 байт Python3.5


 


Код без минимизации



import sys

def unpack(index, size, mp):
return sum([mp[index + j] << 8 * j for j in range(size)])

hexmap = open(sys.argv[1], 'rb').read()
shift = unpack(10, 4, hexmap)
width = unpack(18, 4, hexmap)
height = unpack(22, 4, hexmap)
symbols = ['█', '▓', '▒', '░', ' ']
delta = 256 / len(symbols)
for i in range(height):
line = []
for j in range(width):
k = 4 * (j + (height - i - 1) * height) + shift
if hexmap[k + 3] == 0:
line.append('·')
else:
max_component = max(hexmap[k: k + 2])
line.append(symbols[int(max_component / delta)])
print(''.join(line))

Код с минимизацией



import sys
r=range
m=open(sys.argv[1],'rb').read()
v=(lambda i:sum([m[i+j]<<8*j for j in r(4)]))
h=v(22)
for i in r(h):print(''.join([(lambda k:'█▓▒░ '[int(max(m[k:k+2])/51.1)] if m[k+3] else '·')(4*(j+(h-i-1)*h)+138)for j in r(v(18))]))

Одной строкой



"import sys\nr=range\nm=list(open(sys.argv[1],'rb').read())\nv=(lambda i:sum([m[i+j]<<8*j for j in r(4)]))\nh=v(22)\nfor i in r(h):print(''.join([(lambda k:'█▓▒░ '[int(max(m[k:k+2])/51.1)] if m[k+3] else '·')(4*(j+(h-i-1)*h)+138)for j in r(v(18))]))"

Запуск программы



python file_name.py <image_name.bmp>

Изменено пользователем Seryoga
  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Нео, для кого в шапке написано - "Обсуждаем в чате или в IRC, чтобы не захламлять тему." ?

Ты мог вместо этого своего "плюс один" - просто лайк Лёхе поставить. Репа бы апнулась и тема бы не захламлялась.

Манифест и демократия.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Нео, для кого в шапке написано - "Обсуждаем в чате или в IRC, чтобы не захламлять тему." ?

А кстати, чисто ради интереса хочу узнать, почему именно в ирке этот конкурс не сделали именно для обитателей ирки? А то я видел, даже страничку создали там отдельную от форума обособленно, написали захватывающий интересный рассказ о том, где эндерменсы украли золотые байтсы, трогательная и увлекательная подробная душещипательная глубокая история возникновения названия конкурса , прогулки по сайтам, блоги, чатсы, ирки, призы в стиме и прочее, не упомянули там только твиттер Крутого, ЖЖ-шку, Комсомольскую правду, и лондонскую газету Таймс о конкурсе на первой полосе. Может есть смысл эту всю сагу увлекательную на форум залить?  :)

 

[удалю  потом свой вопрос, чтобы не захламлять тему=)]

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А кстати, чисто ради интереса хочу узнать, почему именно в ирке этот конкурс не сделали именно для обитателей ирки? А то я видел, даже страничку создали там отдельную от форума обособленно, написали захватывающий интересный рассказ о том, где эндерменсы украли золотые байтсы, трогательная и увлекательная подробная душещипательная глубокая история возникновения названия конкурса , прогулки по сайтам, блоги, чатсы, ирки, призы в стиме и прочее, не упомянули там только твиттер Крутого, ЖЖ-шку, Комсомольскую правду, и лондонскую газету Таймс о конкурсе на первой полосе. Может есть смысл эту всю сагу увлекательную на форум залить?  :)

 

[удалю  потом свой вопрос, чтобы не захламлять тему=)]

 

Алекс, вот чем тебе IRC не нравится? :)

РК у меня не идёт, Мамбла у Фингера, а у форумного чата нет нормального протокола. IRC идёт везде и на всём, даже на холодильниках. Очень удобно.

 

А конкурс вообще-то для форумчан. И он тут на форуме - в теме и блого-посте - описан.

Страничка отдельная - типа флаера, листовки. Там кастомный дизайн. :D

Я не стал дублировать инфу, просто создал тему чтобы постить решения. Можно и на форум это всё залить, в принципе.

 

По стилю - это конкурс типа того же 10 Hello world!, только более сложный и развёрнутый.

 

 

Манифест и демократия.

 

*facepalm*

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Love2D

Изображение необходимо разместить в папке проекта под именем Image.png

function love.load()
  im=love.image.newImageData('Image.png')
end

function love.draw()
  for y=1,im:getHeight() do
    for x=1,im:getWidth() do
		r,g,b,a=im:getPixel(x-1,y-1)
		r=(r+g+b)/3
		love.graphics.print(((a==0 or r>205) and " " or r>154 and "." or r>102 and "/" or r>51 and "=" or "#"),x*10,y*10)
	end
  end
end

333 байта

Исходное изображение post-7-0-25096900-1473071940.png

Результат post-7-0-71678600-1473071968_thumb.png

  • Like 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Love2D

...

 

Под условия попадает не совсем (PNG, внешняя либа).

Но интересный вариант :)

Изменено пользователем Totoro

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Под условия попадает не совсем (PNG, внешняя либа).

Но интересный вариант :)

function love.load()
  im=love.image.newImageData('Image.bmp')
end

function love.draw()
  for y=1,im:getHeight() do
    for x=1,im:getWidth() do
		r,g,b=im:getPixel(x-1,y-1)
		r=(r+g+b)/3
		love.graphics.print(r>205 and " " or r>154 and "." or r>102 and "/" or r>51 and "=" or "#",x*10,y*10)
	end
  end
end

319 байт

После минимизации

l=love i=l.image.newImageData('Image.bmp')function l.draw()for y=1,i:getHeight()do for x=1,i:getWidth()do r,g,b=i:getPixel(x-1,y-1)r=r+g+b l.graphics.print(r>615 and" "or r>462 and"."or r>306 and"/"or r>153 and"="or"#",x*9,y*9)end end end 

238 байт

Результат почти тот же.post-7-0-37663600-1473074208_thumb.png

Изменено пользователем Zer0Galaxy
  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
...

Результат почти тот же.attachicon.gifResult.png

 

 

Это понятно. Я имел ввиду, что смысл конкурса - запилить парсинг картинки. И юзать для этого внешнии либы нельзя, конечно. Потому что в них эта задача уже решена за тебя.

Но подход креативный. =)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А где я тут юзал внешние либы? Я использовал возможности среды программирования. Или функции чтения из файла и вывода на экран тоже нужно самому реализовывать?

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А где я тут юзал внешние либы? Я использовал возможности среды программирования. Или функции чтения из файла и вывода на экран тоже нужно самому реализовывать?

 

Love2D - как и любой другой game framework - это внешняя библиотека. Язык в данном случае - Lua (самый что ни на есть обычный).

Хотя формально ты может быть и прав. Тут довольно размыто определение того, что считать самостоятельным языком.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Мне одному кажется, что Totoro специально создал конкурс здесь, чтобы выбрать лучший результат и поучаствовать в оригинальном конкурсе? (я кстати прочитал, там в качестве подарка ключ в стиме выдать могут :) )

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Мне одному кажется, что Totoro специально создал конкурс здесь, чтобы выбрать лучший результат и поучаствовать в оригинальном конкурсе? (я кстати прочитал, там в качестве подарка ключ в стиме выдать могут :) )

 

конкурс создал фингер, тоторе же хватило сил создать тему, фингер побоялся

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гость
Эта тема закрыта для публикации сообщений.

×