Обновить
128K+

Java *

Объектно-ориентированный язык программирования

152,41
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Делаем визуальный web-редактор документов на основе LibreOffice, jodconverter и TinyMCE

Время на прочтение7 мин
Охват и читатели29K
Как же я люблю спецификацию офиса!С написания предыдущей статьи про генерацию Excel документов по шаблону прошло много времени и задача несколько изменилась. Новая задача была поставлена следующим образом: из готового документа excel или word сделать шаблон через веб-интерфейс. В процессе формирования подставлять в шаблон нужные значения, убирать и/или «клонировать» куски шаблона. После формирования, документ должен быть доступен пользователю для визуального редактирования в браузере. Готовый документ должен сохраниться на сервере, быть доступным для скачивания пользователем как в своём расширении (*.doc/*.xls), так и в pdf. При этом верстка скачиваемого файла должна быть идентична шаблону, который был загружен в самом начале (без всяких искажений полей и областей печати).
Что же, задача есть — будем решать!
Читать дальше →

Исключения в Java, Часть I (try-catch-finally)

Время на прочтение23 мин
Охват и читатели457K
Это первая часть статьи, посвященной такому языковому механизму Java как исключения (вторая (checked/unchecked) вот). Она имеет вводный характер и рассчитана на начинающих разработчиков или тех, кто только приступает к изучению языка.

Также я веду курс «Scala for Java Developers» на платформе для онлайн-образования udemy.com (аналог Coursera/EdX).

1. Ключевые слова: try, catch, finally, throw, throws
2. Почему используем System.err, а не System.out
3. Компилятор требует вернуть результат (или требует молчать)
4. Нелокальная передача управления (nonlocal control transfer)
5. try + catch (catch — полиморфен)
6. try + catch + catch + ...
7. try + finally
8. try + catch + finally
9. Вложенные try + catch + finally


1. Ключевые слова: try, catch, finally, throw, throws


Механизм исключительных ситуаций в Java поддерживается пятью ключевыми словами
  • try
  • catch
  • finally
  • throw
  • throws


«Магия» (т.е. некоторое поведение никак не отраженное в исходном коде и потому неповторяемое пользователем) исключений #1 заключается в том, что catch, throw, throws можно использовать исключительно с java.lang.Throwable или его потомками.
Читать дальше →

Слишком быстрый, слишком мегаморфный: что влияет на производительность вызова метода в Java?

Время на прочтение9 мин
Охват и читатели22K
От переводчика:
спор сторонников написания final везде и всюду и их противников сродни спору остроконечников и тупоконечников. Как и в некоторых других сообществах, в нашей компании этот вялотекущий спор шел годами. И только эта статья Ричарда Вэрбёртона (Richard Warburton) позволила нашим остроконечникам взять верх.


О чём речь?

Начнем с небольшого рассказа. Несколько недель назад я отправил в список рассылки Java core libs своё предложение убрать модификатор final с некоторых методов. В результате возникло несколько тем для дискуссии. Одна из них, например, — выяснить, в какой степени ухудшится производительность вызова метода, который был final, если этот final с него убрать.

У меня были некоторые соображения о том, возникнет регрессия производительности или нет, но я сначала попытался узнать, публиковал ли кто-нибудь уже результаты бенчмарков по этому вопросу. К сожалению, я ничего не смог найти. Это не означает, что они не существуют или что другие люди не исследовали ситуацию, но я не встречал никакого кода, прошедшего экспертную проверку. Так что самое время написать несколько бенчмарков.
Читать дальше →

Лямбда-выражения в Java 8

Время на прочтение19 мин
Охват и читатели469K
В новой версии Java 8 наконец-то появились долгожданные лямбда-выражения. Возможно, это самая важная новая возможность последней версии; они позволяют писать быстрее и делают код более ясным, а также открывают дверь в мир функционального программирования. В этой статье я расскажу, как это работает.

Java задумывалась как объектно-ориентированный язык в 90-е годы, когда объектно-ориентированное программирование было главной парадигмой в разработке приложений. Задолго до этого было объектно-ориентированное программирование, были функциональные языки программирования, такие, как Lisp и Scheme, но их преимущества не были оценены за пределами академической среды. В последнее время функциональное программирование сильно выросло в значимости, потому что оно хорошо подходит для параллельного программирования и программирования, основанного на событиях («reactive»). Это не значит, что объектная ориентированность – плохо. Наоборот, вместо этого, выигрышная стратегия – смешивать объектно-ориентированное программирование и функциональное. Это имеет смысл, даже если вам не нужна параллельность. Например, библиотеки коллекций могут получить мощное API, если язык имеет удобный синтаксис для функциональных выражений.

Главным улучшением в Java 8 является добавление поддержки функциональных программных конструкций к его объектно-ориентированной основе.
Читать дальше →

YARG — open-source библиотека для генерации отчётов

Время на прочтение11 мин
Охват и читатели38K
Практически каждый разработчик, создающий информационные системы, сталкивается с необходимостью формирования различных отчетов и печатных форм. Это характерно и для большинства приложений разработанных на нашей платформе. Например, в системе, над которой я работаю в настоящее время, их 264. Для того чтобы не писать каждый раз логику формирования отчетов с нуля, мы разработали специальную библиотеку (под катом будет объяснено, почему нам не подошли существующие). Называется она YARG — Yet Another Report Generator.
YARG позволяет:
  • Генерировать отчет в формате шаблона или конвертировать результат в PDF;
  • Создавать шаблоны отчетов в привычных и распространенных форматах: DOC, ODT, XLS, DOCX,XLSX, HTML;
  • Создавать сложные XLS и XLSX шаблоны: с вложенными областями данных, графиками, формулами и т.д.;
  • Использовать в отчетах изображения и HTML-разметку;
  • Хранить структуру отчетов в формате XML;
  • Запускать standalone приложение для генерации отчетов, что делает возможным использование библиотеки вне Java-экосистемы (например для генерации отчетов в PHP);
  • Интегрироваться с IoC-фреймворками (Spring, Guice).

Эта библиотека используется в платформе CUBA в качестве основы для движка отчетов. Мы развиваем ее с 2010 года, но совсем недавно решили сделать ее открытой, и выложили ее код на GitHub с лицензией Apache 2.0.
Данная статья призвана привлечь к ней внимание сообщества.

Читать дальше →

Создание Zero Player Game, используя libgdx

Время на прочтение6 мин
Охват и читатели16K

Идея


  1. Игровое пространство — клетчатое поле ограниченное рамкой
  2. Существующие типы клеток:
    • Пустая клетка — белый
    • Стена — чёрный
    • Зверь — красный
    • След — коричневый
    • Дом — зелёный
  3. Перемещение зверя оставляет неисчезающий след
  4. При запуске генерируется лабиринт
  5. Зверь знает состояние соседних клеток и на основании этого строит карту при перемещении
  6. При перемещении зверь расходует силы, которые восстанавливаются в доме(+5) или на любой клетке(+1)
  7. При столкновении звери объединяются в стаи(дома переносятся в соседние точки), если несколько зверей одновременно отдыхают в доме их карты объединяются
  8. (Не реализовано)Разные «кланы» случайным образом объединяются или воюют
  9. (Не реализовано)Генетический алгоритм для различных поведений зверей, случайно перемешивающиеся при размножении(+мутации), более перспективный вид выживет в войнах

Читать дальше →

[ libGDX ] Пишем полноценную игру под Android. Часть 2

Время на прочтение21 мин
Охват и читатели45K
Здравствуйте! Не прошло и суток с момента публикации первой части статьи, а я не могу спать, так как есть незаконченное дело и нужно дописать статью. Приступим.
Читать дальше →

[ libGDX ] Пишем полноценную игру под Android. Часть 1

Время на прочтение8 мин
Охват и читатели117K
Здравствуйте! Я решил попробовать себя на поприще game-dev'а и заодно рассказать и показать как это было. Вторая часть здесь.

Игра представляет собой экран, на котором расположены созвездия. Каждая звезда этого созвездия имеет свой цвет (нота). Например, ноту «До» обычно представляют красным цветом, а «Ми» — желтым. Вот что получится в итоге:

image

Итак, каждый уровень — новое созвездие и новая мелодия. Звезды играют первые четыре ноты, а затем вы должны повторить их в той же последовательности. Затем, к первым четырем нотам добавляются еще четыре и так далее, пока уровень не будет пройден.

Писать будем, используя фреймворк libGDX. Мне он больше всех понравился, как новичку в этом деле. Да и информации по нему я нашел больше. Итак, приступим.
Читать дальше →

Тестирование через абстрактные классы в TestNG

Время на прочтение7 мин
Охват и читатели10K

Вступление


Вы всё ещё тестируете с помощью JUnit и не обращаете внимания на TestNG? Тогда мы идём к вам.

Одним из преимуществ TestNG является возможность создания тестовых массивов данных для одного или нескольких тестов. Но мало кто использует такое преимущество от @DataProvider как пустой набор тестовых данных. В чём оно выражается?

Допустим у нас есть некий тест testData(String value) и метод datas обеспечивающий DataProvider. Если datas вернёт нам массив из 3-х элементов, то testData выполнится 3 раза. Но если datas вернёт нам пустой массив, то testData не выполнится ни разу
Картинки


Давайте попробуем воспользоваться данной особенностью.

Читать дальше →

Мы провели Kotlin Challenge: что в финале?

Время на прочтение4 мин
Охват и читатели5.7K
Утро понедельника? Отличное время вспомнить, что хорошего уже успело случиться, чтобы начать неделю с добрых новостей!

Осенью 2013-го мы затеяли Kotlin Challenge — соревнование по программированию для тех, кто был готов попробовать Kotlin, новый язык программирования для платформы Java. Записались несколько сотен человек, осенью прошли заочные тренировочные туры и четвертьфиналы, в феврале 2014-го — полуфинал, и наконец…
Читаем дальше, а в конце рассказа - разбор олимпиадной задачи

Встраиваем groovy shell в приложение

Время на прочтение2 мин
Охват и читатели8.2K
У нас на работе иногда возникает необходимость получить доступ к работающему java приложению, чтобы посмотреть какие-нибудь данные или подёргать методы. Раньше мы обходились тем, что писали jsp, закидывали в каталог, в котором развёрнуто наше приложение, и затем запрашивали эту jsp. Это было не очень удобно.

И однажды мне пришла в голову мысль облегчить себе жизнь, встроив groovy shell в приложение, сделав доступ к нему через telnet.

Читать дальше →

Вычисление имен свойств во время выполнения в языке Java

Время на прочтение3 мин
Охват и читатели8.6K
Некоторые инструменты могут использовать имена свойств виде значений типа String. Обычно они существуют как константы, заданные литералами. Что же не так? А вот что: во время рефакторинга имена свойств могут измениться, более того, свойства могут вообще исчезнуть. А в константах останутся старые, неактуальные значения.

Можно понадеяться на внимание уставшего разработчика, или на ненаписанные тесты. Но есть более надежный способ.
Читать дальше →

Основные принципы настройки Garbage Collection с нуля

Время на прочтение7 мин
Охват и читатели53K
В данной статье я бы не хотел заострять внимание на принципе работы сборщика мусора — об этом прекрасно и наглядно описано здесь: habrahabr.ru/post/112676. Хочется больше перейти к практическим основам и количественным характеристикам по настройке Garbage Collection в JVM — и попытаться понять насколько это может быть эффективным.

Количественные характеристики оценки эффективности GC


Рассмотрим следующие показатели:

  • Пропускная способность Мера, определяющая способность приложения работать в пиковой нагрузке не зависимо от пауз во время сборки и размера необходимой памяти
  • Время отклика Мера GC, определяющая способность приложения справляться с числом остановок и флуктуаций работы GC
  • Размер используемой памяти Размер памяти, который необходим для эффективной работы GC


Как правило, перечисленные характеристики являются компромиссными и улучшение одной из них ведёт к затратам по остальным. Для большинства приложений важны все три характеристики, но зачастую одна или две имеют большее значение для приложения — это и будет отправной точкой в настройке.
Читать дальше →

Ближайшие события

Microsoft Research запустила браузерную игру-головоломку по обучению программированию

Время на прочтение1 мин
Охват и читатели118K


Microsoft Research в своем блоге анонсировала запуск браузерной игры-головоломки Code Hunt по обучению программированию на C# и Java.
Игроку даются фрагменты кода с заранее неизвестной функциональностью. Цель игры заключается в том, чтобы на основе входных данных и ожидаемого результата, изменить код метода или функции так, чтобы выходные данные соответствовали этому ожидаемому результату.
Читать дальше →

Геокодер OSM на Java

Время на прочтение15 мин
Охват и читатели27K
Привет, дорогие читатели хабра. В этой статье поговорим

  • Про адреса и хранилища данных с нечеткой схемой
  • Про обработку геоданных на java, а именно про Java Topology Suite
  • Про стоимость «простоты» для разработчика
  • Про pure Java nosql документную бд / движок полнотекстового поиска — Elasticsearch.

Читать дальше →

Java Multicore Programming: Lecture #1

Время на прочтение2 мин
Охват и читатели18K
Добрый день.
15 мая была проведен первый вебинар (из 16) курса «Multicore programming in Java». Тут я бы хотел опубликовать материалы, упоминавшиеся на лекции: ссылки на источники, термины, картинки, задание. Возможно кто-то сочтет их полезными для себя.

Также я веду курс «Scala for Java Developers» на платформе для онлайн-образования udemy.com (аналог Coursera/EdX).

Введение




“Железо”


Стоит «посмотреть картинки» в следующих источниках

Читать дальше →

Дорог ли native метод? «Секретное» расширение JNI

Время на прочтение5 мин
Охват и читатели33K

Для чего Java-программисты прибегают к native методам? Иногда, чтобы воспользоваться сторонней DLL библиотекой. В других случаях, чтобы ускорить критичный алгоритм за счет оптимизированного кода на C или ассемблере. Например, для обработки потокового медиа, для сжатия, шифрования и т.п.

Но вызов native метода не бесплатен. Порой, накладные расходы на JNI оказываются даже больше, чем выигрыш в производительности. А всё потому, что они включают в себя:
  1. создание stack frame;
  2. перекладывание аргументов в соответствии с ABI;
  3. оборачивание ссылок в JNI хендлы (jobject);
  4. передачу дополнительных аргументов JNIEnv* и jclass;
  5. захват и освобождение монитора, если метод synchronized;
  6. «ленивую» линковку нативной функции;
  7. трассировку входа и выхода из метода;
  8. перевод потока из состояния in_Java в in_native и обратно;
  9. проверку необходимости safepoint;
  10. обработку возможных исключений.

Но зачастую native методы просты: они не бросают исключений, не создают новые объекты в хипе, не обходят стек, не работают с хендлами и не синхронизованы. Можно ли для них не делать лишних действий?

Да, и сегодня я расскажу о недокументированных возможностях HotSpot JVM для ускоренного вызова простых JNI методов. Хотя эта оптимизация появилась еще с первых версий Java 7, что удивительно, о ней еще никто нигде не писал.
Читать дальше →

Consulo + .NET плагин, спустя два месяца

Время на прочтение2 мин
Охват и читатели6.4K
После моей первой публикации прошло два месяца. После него я немного сменил приоритет на одну задачу. А именно — реализацию дебаггера, хотя бы для Mono .NET.
Читать дальше →

Программирование-по-Контракту в Java

Время на прочтение31 мин
Охват и читатели56K
Добрый день.
В рамках детальной проработки курса удаленного образования «Java Core» я пишу серию публикаций и делаю несколько переводов наиболее популярных статей.

Также я веду курс «Scala for Java Developers» на платформе для онлайн-образования udemy.com (аналог Coursera/EdX).

Сейчас я предлагаю Вам на рассмотрение мой перевод «Programming With Assertions» с некоторыми комментариями.

Оригинальная публикация не только детально объясняет варианты использования ключевого слова assert в Java и то, как реализована поддержка данного механизма на уровне загрузки классов, но также является достаточно неформальным введением в Разработку-по-Контракту (Design-by-Contract).




P.S. Автор признает, что для него лично русский язык намного сложнее языка Java, с благодарностью выслушает в личку о всех замеченных ошибках и постарается их в кратчайшие сроки исправить.



Программирование с утверждениями (oracle.com: Programming With Assertions)

Утверждение (assert) — это оператор (statement) языка программирования Java, который позволяет вам проверить свои предположения о программе. Например, если вы пишете метод, вычисляющий скорость частицы, можно «утверждать», что расчетная скорость меньше скорости света.

Каждое утверждение содержит логическое выражение, которое, по вашему мнению, будет верным в момент выполнения. В противном случае, система выбросит исключение. Проверяя, что логическое выражение на самом деле верно, утверждение (assert) подтверждает ваши предположения (ожидания) о поведении программы, увеличивая уверенность в том, что программа не содержит ошибок.
Читать дальше →

Результаты и обсуждение майского хабрасоревнования: делаем свой ГЛОНАСС

Время на прочтение16 мин
Охват и читатели14K
Итак, настало время подвести итоги прошедшего майского хабрасоревнования. Было прислано 49 решений, удовлетворяющих требованиям по оформлению и 8 решений вне конкурса (позже дедлайна, с ошибками оформления, на неверный адрес). Что-ж, посмотрим, кто что написал.

Хотя в обсуждении топика с самой задачей люди переживали, что самое компактное и самое быстрое решение — это разные вещи, оказалось что решение победителя lany — является и самым компактным, удовлетворяющим всем требованиям. Решение Frommi было вдвое компактнее, 863 байта — но не смогло пройти все тесты. Следующим шло решение ibessonov на 1613 байта — но оно внезапно показало большую ошибку на первом тесте.

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

  1. lany — двойной победитель, 89.9448 баллов и самое компактное решение.
    Самый большой тест (2.4Гб) пройден за 0.61 секунду.
    Смотреть исходник
    //@lany
    public class G{java.io.InputStream I=System.in;int c,i=0,j,m,M;double[]S=new double[512],C=new double[512];byte[]P="111001100011101101".getBytes(),d=new byte[999999];double N=4.0678884e13,L=29.9792458,X,Y,q,F,G,H=1e99;S[]z;S f,g;class S{double x,y,r,q,R,Q;S(){x=new Double(l());y=new Double(l());try{I.read(d);I.skip(9000001);}catch(Exception e){}q=L*o()+L/2;Q=q*q;r=q-L;R=r*r;l();}int o(){int o=0,p;for(;;o+=10){for(p=0;p<18;p++)if(P[p]!=d[o+p*10])break;if(p==18){while(d[--o]>48);return o+1;}}}}void u(double X,double Y){if(X*X+Y*Y<N){double S=d(X,Y);if(S<H){H=S;F=X;G=Y;}}}double d(double x,double y){double q=0,Q=-1,X,Y;for(S s:z){X=x-s.x;Y=y-s.y;X=X*X+Y*Y;if(X>s.Q)q+=X-s.Q;else if(X<s.R)q+=s.R-X;else if(q==0){Y=Math.sqrt(X);Q*=Math.min(s.q-Y,Y-s.r)*.1;}}return q>0?q:Q;}void b(double r,double R){if(r+R>q){double d=Math.abs(r*r-R*R+q*q)/2/q,h=Math.sqrt(r*r-d*d),x=f.x+X*d,y=f.y+Y*d;u(x-Y*h,y+X*h);u(x+Y*h,y-X*h);}}String l(){char[]o=new char[99];int p=0,b;try{while((b=I.read())!=10)o[p++]=(char)b;}catch(Exception e){}return new String(o,0,p).trim();}public static void main(String[]a){new G();}G(){for(;i<512;i++){q=Math.PI*i/256;S[i]=Math.sin(q);C[i]=Math.cos(q);}c=new Short(l());z=new S[c];for(i=0;i<c;)z[i++]=new S();for(i=1;i<c&&H>0;i++)for(j=0;j<i&&H>0;j++){f=z[i];g=z[j];X=g.x-f.x;Y=g.y-f.y;q=Math.sqrt(X*X+Y*Y);X/=q;Y/=q;b(f.q,g.q);b(f.r,g.q);b(f.q,g.r);b(f.r,g.r);}double x=F,y=G,r=d(x,y),t=r<1e10?1e3:3e6,u,v,w,R;while(t>.1&&(i++<999||r>0)){R=r;X=x;Y=y;for(M=4;M<513&&R==r;M*=2){for(m=0;m<M;m++)if(M<5||m%2>0){j=m*512/M;u=x+S[j]*t;v=y+C[j]*t;if(u*u+v*v<N){w=d(u,v);if(w<R){X=u;Y=v;R=w;}}}}if(R<r){x=X;y=Y;r=R;}else t/=2;}System.out.println(x+" "+y);}}
  2. @AKashta — 86.9558 балла, на самом большом тесте вдвое быстрое lany, но немного проиграл по точности.
    Смотреть исходник
    //@AKashta
    
    import java.io.*;
    import java.util.ArrayList;
    
    public class Main {
    
        public static final boolean ADVANCED_MODE = true;
        public static final int MAX_POINTS = 50;
        public static final double PRECISION = 30;
        public static final int THRESHOLD = 300;
    
        public static final String START_TOKEN = "111001100011101101";
        public static final long DATA_LENGTH = 10000000;
        public static final long SPEED = 299792458;
        public static final long EARTH_R = 6378000;
        public static final long MIN_SAT_POS = 10000000;
        public static final long MAX_SAT_POS = 20000000;
        public static final int MIN_OFFSET = (int)((MIN_SAT_POS - EARTH_R) * DATA_LENGTH / SPEED);
        public static final int MAX_OFFSET = (int)((MAX_SAT_POS + EARTH_R) * DATA_LENGTH / SPEED);
    
        public static void main(String args[ ]) {
            //long startTime = System.currentTimeMillis();
            try {
                DataInputStream in = new DataInputStream(System.in);
                DataReader reader = new DataReader(in);
                Point result = null;
    
                int q = reader.readInt();
                ArrayList<Circle> sats = new ArrayList<Circle>(q);
                for(int i = 0; i < Math.min(q, MAX_POINTS); i++) {
                    double x = reader.readDouble();
                    double y = reader.readDouble();
                    int offset = reader.readOffset();
    
                    double radius = ((double)SPEED / DATA_LENGTH * offset);
    
                    sats.add(new Circle(new Point(x, y),  radius));
                }
    
                if(sats.size() == 2) {
                    ArrayList<Point> points = sats.get(0).intersect(sats.get(1));
                    for(Point p : points) {
                        result = p;
                        break;
                    }
                }  else {
                    if(ADVANCED_MODE) {
                        result = advancedCalc(sats);
                    } else {
                        result = simpleCalc(sats);
                    }
                }
    
                System.out.println(result.x + " " + result.y);
                //long time = (System.currentTimeMillis() - startTime);
                //System.out.println("Time: " + time);
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    
        public static Point findRefPoint(ArrayList<Circle> sats){
            ArrayList<Point> points = new ArrayList<Point>();
            for(int i = 0; i < 2; i++) {
                for(int j = i + 1; j < 3; j++) {
                    points.addAll(sats.get(i).intersect(sats.get(j)));
                }
            }
    
            Point p0 = null, p1 = null, p2 = null;
            for(Point p : points) {
                for(Point t : points) {
                    if(p1 == null && t != p && p.distance(t) < THRESHOLD){
                        p1 = t;
                        continue;
                    }
                    if(p1 != null && t != p && t != p1 && p.distance(t) < THRESHOLD){
                        p2 = t;
                        break;
                    }
                }
                if(p1 != null && p2 != null) {
                    p0 = p;
                    break;
                } else {
                    p1 = null;
                    p2 = null;
                }
            }
            return new Point((p0.x + p1.x + p2.x) / 3, (p0.y + p1.y + p2.y) / 3);
        }
    
        public static Point advancedCalc(ArrayList<Circle> sats){
            ArrayList<Point> allPoints = new ArrayList<Point>();
            for(int i = 0; i < sats.size() - 1; i++) {
                for(int j = i + 1; j < sats.size(); j++) {
                    allPoints.addAll(sats.get(i).intersect(sats.get(j)));
                }
            }
    
            int count = 0;
            double sumX = 0;
            double sumY = 0;
    
            for(Point p : allPoints) {
                boolean containsInAll = true;
                for (Circle sat : sats){
                    if(!sat.hasPoint(p)) {
                        containsInAll = false;
                        break;
                    }
                }
                if(containsInAll) {
                    count++;
                    sumX += p.x;
                    sumY += p.y;
                }
            }
            return new Point(sumX / count, sumY / count);
        }
    
        public static Point simpleCalc(ArrayList<Circle> sats){
            int count = 0;
            double sumX = 0;
            double sumY = 0;
    
            Point refPoint = findRefPoint(sats);
            for(int i = 0; i < sats.size() - 1; i++) {
                for(int j = i + 1; j < sats.size(); j++) {
                    for(Point p : sats.get(i).intersect(sats.get(j))) {
                        if(refPoint.distance(p) < THRESHOLD) {
                            count++;
                            sumX += p.x;
                            sumY += p.y;
                        }
                    }
                }
            }
            return new Point(sumX / count, sumY / count);
        }
    
        public static class DataReader {
            private DataInputStream _in;
    
            public DataReader(DataInputStream in){
                _in = in;
            }
    
            public int readOffset() throws Exception {
                byte firstByte = _in.readByte();
                int offset = 1;
                while( _in.readByte() == firstByte) {
                    offset++;
                }
                int needToSkip = ((MIN_OFFSET - offset) / 10) * 10;
                _in.skipBytes(needToSkip);
                offset += needToSkip;
    
                byte[] buffer = new byte[MAX_OFFSET - offset];
                _in.read(buffer);
                _in.skipBytes((int) DATA_LENGTH - offset - buffer.length - 1 + 2);
    
                StringBuilder sb = new StringBuilder(buffer.length / 10);
                for(int i = 0; i < buffer.length / 10; i++ ){
                    sb.append((char) buffer[i * 10]);
                }
    
                int index = sb.indexOf(START_TOKEN)* 10;
    
                return index + offset;
            }
    
            public String readLine() throws Exception {
                StringBuilder sb = new StringBuilder();
                char c;
                while((c = (char)_in.readByte()) != '\r') {
                    sb.append(c);
                }
                _in.readByte(); // read '\n' char
                return  sb.toString();
            }
    
            public int readInt() throws Exception {
                String s = readLine();
                return Integer.parseInt(s);
            }
    
            public Double readDouble() throws Exception {
                String s = readLine();
                return Double.parseDouble(s);
            }
        }
    
        public static class Point {
            public double x;
            public double y;
    
            public Point(double x, double y) {
                this.x = x;
                this.y = y;
            }
    
            public double distance() {
                return Math.sqrt(x*x + y*y);
            }
    
            public double distance(Point p) {
                return Math.sqrt(Math.pow(x - p.x, 2) + Math.pow(y - p.y, 2));
            }
        }
    
        public static class Circle {
            public Point center;
            public double radius;
            public Circle(Point p, double r) {
                center = p;
                radius = r;
            }
    
            public ArrayList<Point> intersect(Circle c) {
                ArrayList<Point> result = new ArrayList<Point>();
    
                double dx = c.center.x - center.x;
                double dy = c.center.y - center.y;
                double d = Math.sqrt((dy * dy) + (dx * dx));
    
                if(d < Math.abs(radius - c.radius)) {
                    if(radius < c.radius)
                        radius += Math.abs(radius - c.radius) - d + 0.1;
                    else
                        c.radius += Math.abs(radius - c.radius) - d + 0.1;
                }
                if (d > (radius + c.radius)) {
                    double add = (d - (radius + c.radius))/ 2.0 + 0.1;
                    radius += add;
                    c.radius += add;
                }
    
                if (d > (radius + c.radius) || d < Math.abs(radius - c.radius)) {
                    //System.out.println("do not intersect");
                    return result;
                }
    
                double a = ((radius * radius) - (c.radius * c.radius) + ( d *d)) / (2.0 * d);
    
                Point p2 = new Point(center.x + (dx * a/d), center.y + (dy * a/d));
    
                double h = Math.sqrt((radius * radius) - (a*a));
                double rx = -dy * (h/d);
                double ry = dx * (h/d);
    
                Point p = new Point(p2.x + rx, p2.y + ry);
                if(p.distance() <= EARTH_R) {
                    result.add(p);
                }
                p = new Point(p2.x - rx, p2.y - ry);
                if(p.distance() <= EARTH_R) {
                    result.add(p);
                }
    
                return result;
            }
    
            public boolean hasPoint(Point p) {
                double d = center.distance(p);
                return Math.abs(d - radius) <= PRECISION;
            }
        }
    }
  3. @habrunit — 83.9379 балла, буквально вырвал призовое место из рук Staker.
    Смотреть исходник
    //@habrunit
    //package olimp;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.UnsupportedEncodingException;
    import java.security.NoSuchAlgorithmException;
    import static java.lang.Math.*;
    
    public class Olimp {
    	private static int cash[]={0xc0001200,0x10818201,0x51feba02,0x1483a003,0xb6ffc304,0x8d953105,0x1b2e7e06,0x780a707,0x59041a08,0x283b1c09,0x5818430a,0xc13b950b,0x3921ed0c,0x599b60d,0x99c8400e,0x2612640f,0xb7b0ca10,0x8c17d11,0xd35fda12,0x96863f13,0xca7ea414,0x90875415,0xc860e416,0x6239c317,0x9f39d418,0xccc48419,0x3f43d11a,0x9e366d1b,0x37fc9a1c,0x103bd91d,0xe96c501e,0x80ccf81f,0x602aca20,0xed28b721,0xcedf2d22,0xd2da9e23,0x93574024,0xebba4125,0x77fcc26,0xf8eb1a27,0xc6e09728,0x58dfe129,0xc776642a,0x6688342b,0x102a252c,0xedec802d,0xdf737f2e,0x4b5b402f,0x9c29fb30,0x93300a31,0xc30d2b32,0xabe73633,0x61f4fa34,0xf4334c35,0xd27b8a36,0xf7b63e37,0x602d9038,0x2e8aff39,0x4e62003a,0xc489143b,0x4e5ed53c,0x57a46f3d,0xf6630b3e,0xb392f53f,0xba827340,0x5b9b7e41,0x3e9d1f42,0x29b2c743,0x47f8644,0xe4d74745,0xf1263046,0x3d44e47,0xb1905148,0xd079d849,0x66f16d4a,0x281ff94b,0x4cbc284c,0xe364e94d,0x5fda1a4e,0x4628d24f,0x47d17d50,0x53ca2751,0x6738c52,0x2a1c9653,0xcdab0454,0x7429e855,0x91c38556,0xb3c8ab57,0xa98cb258,0x26151d59,0x5525b75a,0xd955c75b,0x51c3475c,0x8350855d,0x1c30b65e,0x70339d5f,0x78a88460,0x4cc2a361,0x12464c62,0x5a34b63,0x3fee8864,0xa8633565,0x3e23d766,0xf8cd5767,0x52432068,0x9cae0969,0x63aa1d6a,0x8742826b,0x75e67b6c,0x2ef696d,0x25006d6e,0x89daa76f,0xbbb71870,0x2faca571,0x71374172,0x9b818673,0xa0de6274,0x29326075,0xb2401776,0x8edcb677,0x7a265378,0x87dd7779,0xb726ce7a,0x99f0397b,0x81a8967c,0x97d0437d,0xc9147e,0x27a1a17f,0xabd65680,0xc405e681,0xc0107482,0xe63b7783,0x16d43984,0x37c8e085,0xc6f26286,0x151dac87,0x67c36588,0xe593b589,0x669e388a,0x5c46a68b,0xb822fe8c,0x6455d18d,0x54b49d8e,0x475edc8f,0xfa8a9690,0xa38c7d91,0xa25f6692,0x32b9a193,0x22bf7c94,0xa72cfb95,0xcaa48696,0x78639e97,0x5dca8798,0xe263e99,0x59c599a,0x855a4f9b,0x4e66949c,0x3a27d89d,0xca15ec9e,0xe443da9f,0xaeaea3a0,0xdc6cdca1,0xa3bb51a2,0xd0f12da3,0xfcd7cda4,0x959c62a5,0x9e276ca6,0x67caeca7,0xc36d51a8,0xe76712a9,0x95d4b5aa,0xe6b1a1ab,0x60979aac,0xae2d55ad,0xf73e82ae,0x87622af,0x55678db0,0xf3813ab1,0x66bd2ab2,0x640762b3,0xab7d25b4,0xce243ab5,0x565e39b6,0x9389fcb7,0xecb84db8,0x8da369b9,0x2b1138ba,0x1a1b3ebb,0xa6a40cbc,0x2659acbd,0xb90ac3be,0xbb61e9bf,0x17dc81c0,0xf9cb57c1,0x1f2c47c2,0x177c6ec3,0x68cb55c4,0x94648fc5,0xb6c33ec6,0x9e71ffc7,0x21d49c8,0x1c1f96c9,0x40fdf8ca,0x608471cb,0x90c71acc,0x83049fcd,0x31232bce,0xa755d0cf,0x2995fd0,0x8ef786d1,0xaf7ae2d2,0x49e5f9d3,0xb621d1d4,0xa30ef5d5,0x75e168d6,0x6fcb3d7,0xe83308d8,0x29c1ead9,0x6b000ada,0xf37c94db,0xe2884cdc,0x7f92e0dd,0x93836ade,0x633232df,0xe29bc4e0,0x8e761fe1,0x31a905e2,0xd46a41e3,0x159184e4,0xd3f654e5,0x6abdbde6,0x865f3be7,0x9f7c41e8,0xb6e13de9,0xae2525ea,0x62d6c9eb,0x271459ec,0x1a13ffed,0x173ed9ee,0x1d2edaef,0x44366bf0,0xc9928f1,0x3fb38bf2,0xdf3dacf3,0x1b5250f4,0xf5f486f5,0x6a7c18f6,0xfce055f7,0xde547ff8,0x35a76ef9,0x2d3666fa,0xa4ba58fb,0x83f9f6fc,0xedb424fd,0xcc4d8fe,0xe0f0baff};
    	private static int cashLen[]={0x328aa,0x6144d,0xb900e,0x3ef04,0x7a10,0xc65aa,0x85819,0x6acf,0x16e30,0x3c13e,0x95b7b,0xcdfba,0xdd3e0,0xbae88,0x1406b,0x2ae9a,0x7bf85,0x17d72,0x9e4cd,0x8e16a,0x754b6,0x68e5c,0xd4a89,0xd6904,0x501a8,0x496da,0x21606,0x3d080,0x98942,0x4f269,0x374f4,0x8f0af,0xa9be5,0xc74e5,0x1f782,0x3fe46,0xc0a16,0xc37da,0x8a462,0x31968,0x510eb,0x59a3c,0x19bf6,0xa4f9b,0xaf773,0xb15f4,0xc8424,0xe10f0,0xb80c2,0x97a00,0x3dfc2,0x90f31,0x94c38,0xf1440,0xa1294,0x6cb64,0xca2b1,0x9d58a,0x632d8,0x42c0c,0x112a4,0x56c76,0xf23e2,0xe8af6,0x93cf6,0x29016,0x848d6,0xac9aa,0xe2f62,0x7733a,0x4b561,0x48799,0xd3b4a,0xe5d49,0xcd078,0x80bce,0x1e84,0xe7bad,0x2dc60,0x5202c,0x10362,0x74574,0x40d88,0xb718,0x9b707,0x35670,0x13128,0xbfada,0x3b1fc,0xcfe57,0x41ccc,0xd59e,0xd2c03,0x67f1b,0x2eba2,0x8952,0xe4e0d,0xb06b4,0x7de08,0x1c9bc,0x57bb8,0x14fac,0xaba6b,0xd59c5,0x26250,0x6bc24,0xb7184,0x38436,0xee717,0x121e6,0x46916,0x9894,0xe019d,0x18cb4,0x1d8fe,0x53eb0,0x83998,0x52f6e,0x39379,0x337ec,0xa4059,0xc4724,0x6daa6,0x5a97e,0x726f0,0x66097,0x6f92a,0x717ae,0xa5ee4,0x73632,0x2348a,0x0,0xc289a,0x7ed4a,0xd784f,0x6e9e8,0x6238e,0xdb54c,0xbeb93,0x92db5,0x66fd8,0x9988a,0x4c4a0,0xe6c69,0x5f5c8,0xd1cb8,0x5b8c0,0x64212,0x1ba7a,0xf420,0x5e686,0xd878a,0xbcd0c,0x7086c,0xe9a3b,0xad8ec,0x54df2,0x5d744,0x763fa,0xe3ecf,0x8d22d,0xb6243,0x9f412,0x206c5,0x9a7c8,0x9c64c,0xcc12f,0x81b12,0x89520,0x96abc,0xe204a,0x365b2,0x7b045,0xa7d6,0x44a90,0xd0d84,0x4e325,0xb3485,0x29f58,0x55d34,0x459d3,0xb253c,0x4c4a,0x5b8c,0xda610,0xea98d,0x885de,0xc65a,0x69d9e,0xc9367,0x4a61c,0xa3117,0x8b3a4,0xd96c8,0x65154,0xde316,0x6ace0,0x3d08,0x5c803,0xbbdcd,0xb43bc,0xc565e,0xa0351,0xf33a7,0xa7d60,0x791be,0xdc4ad,0x280d4,0x1e840,0x2dc6,0x7827c,0xdf25d,0xa8ca8,0x91e73,0xf42,0x8fff1,0x47856,0x7cec6,0x243ce,0xe4de,0xb5305,0x82a53,0x2cd22,0x3472e,0x58afa,0xc195a,0xcb1ec,0xb9f48,0x8675a,0xae834,0xceef9,0xbdc52,0x2bddc,0x8769c,0x7a100,0x7fc91,0x8c2ea,0xa21d5,0x22548,0x3a2bc,0x6050b,0x1ab38,0xef5b9,0xaab26,0xeb8b3,0x15eee,0x43b4e,0x27192,0x2fae4,0xa6e29,0xec7fb,0x2530e,0x4d3e2,0xed769,0x30a26,0xf0568};
    	Circle circles[];
    	double kof=29.9792458;
    	// 
    	static InputStream in;
    	// 
    	final int maxLen10=10000000;
    	final int maxLen1=maxLen10/10;
    	final int maxLenB=16384;
    	// 
    	final byte buf[]=new byte[maxLenB];
    	int posBuf=0;
    	int lenBuf=0;
    	
    	public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException, FileNotFoundException, IOException {
    		
    //		Pset tests[]=new Pset[]{new Pset(-1.81683e+006,-1.74334e+006),new Pset(3.06932e+006, -2.59405e+006),new Pset(3420803.233, -1950298.548)};
    //		long t=System.currentTimeMillis();
    //
    //		for(int i=0;i<tests.length;i++){
    //			in=new FileInputStream("test"+(i+1)+".in");
    //			Pset answer=new Pset();
    //			new Olimp(answer);
    //			answer.printDlta(tests[i]);
    //		}
    //		System.out.println("end"+(System.currentTimeMillis()-t));
    
    
    
    		//in=new FileInputStream("test1.in");
    		in=System.in;
    		Pset answer=new Pset();
    		new Olimp(answer);
    		answer.print();
    		
    	}
    	
    	
    	double readDouble(){
    		while(isBR(buf[posBuf]))posBuf++;
    		int start=posBuf;
    		while(!isBR(buf[posBuf]))posBuf++;
    		String s=new String(buf,start,posBuf-start);
    		while(isBR(buf[posBuf]))posBuf++;
    		return Double.parseDouble(s);
    	}
    	static final boolean isBR(final byte val){
    		return val==13 || val==10 || val==32;
    	}
    	void readMin500()throws IOException{
    		while(lenBuf<500){
    			int l=in.read(buf,lenBuf,maxLenB-lenBuf);
    			if(l==-1)
    				throw new IOException();
    			lenBuf+=l;
    		}
    	}
    	void read()throws IOException{
    		if(posBuf>=maxLenB){
    			posBuf%=maxLenB;
    			lenBuf=0;
    		}
    		int l=in.read(buf,lenBuf,maxLenB-lenBuf);
    		if(l==-1)
    			throw new IOException();
    		lenBuf+=l;
    	}
    
    	private Olimp(final Pset answer)throws IOException{	
    		readMin500();
    		circles=new Circle[(int)readDouble()];
    		for(int sp=0;sp<circles.length;sp++){
    			readMin500();
    			circles[sp]=new Circle(readDouble(), readDouble());	
    
    			int readData=0;
    			int shift=0;
    			{
    				byte temp=buf[posBuf];
    				while(buf[posBuf+shift]==temp)
    					shift++;
    				shift%=10;
    				posBuf+=shift;
    				readData+=shift;
    			}
    			
    			int data=0;
    			for(int i=0;i<32;i++,posBuf+=10){
    				data<<=1;
    				data|=buf[posBuf]==48?(byte)0:(byte)1;
    			}
    			readData+=320;
    			
    			m1:while(posBuf<maxLenB){
    				for(;posBuf<lenBuf;posBuf+=10,readData+=10){
    					if(cash[data&0xFF]==data){
    						double len=            readData             -320 +maxLen10-cashLen[data&0xFF]*10   ;
    						circles[sp].r=len*kof;
    						break m1;
    					}
    							
    					data<<=1;
    					data|=buf[posBuf]==48?(byte)0:(byte)1;
    				}
    				read();
    			}
    			in.skip(maxLen10-(readData+(lenBuf-posBuf)));
    			posBuf=0;
    			lenBuf=0;
    		}
    		int testPset=1;
    		for(int i=2;i<circles.length;i++){
    			if(circles[testPset].r<circles[i].r){
    				testPset=i;
    			}
    		}
    		Pset p0=new Pset();
    		Pset p1=new Pset();
    		int gggg=intersection(circles[0],circles[testPset],p0,p1);
    		double delta0=precisionAll(p0,circles);
    		if(gggg==1){
    			answer.x=p0.x;
    			answer.y=p0.y;
    			return;
    		}
    		double delta1=precisionAll(p1,circles);
    		if(delta0<delta1){
    			answer.x=p0.x;
    			answer.y=p0.y;
    		}else{
    			answer.x=p1.x;
    			answer.y=p1.y;
    		}
    	}
    	static double pow2(double x){
    		return x*x;
    	}
    	static double precisionAll(Pset p0,Circle[] circles){
    		double delta=0;
    		Pset sum=new Pset();
    		Pset temp=new Pset();
    		for(int j=1;j<7;j++){
    			sum.x=0;
    			sum.y=0;
    			for(int i=0;i<circles.length;i++){
    				precision(p0,circles[i],temp);
    				sum.x+=temp.x;
    				sum.y+=temp.y;
    				delta=pow2(temp.x-p0.x)+pow2(temp.y-p0.y);
    			}
    			p0.x=sum.x/circles.length;
    			p0.y=sum.y/circles.length;
    		}
    		return 	delta;
    	}
    	static void precision(Pset pset,Circle circle,Pset returnPset){
    		double dx=pset.x-circle.x;
    		double dy=pset.y-circle.y;
    		double dz=circle.distanceTo(pset);
    		if(dz<0.0000001){
    			if(circle.r<0.000001){
    				returnPset.x=circle.x;
    				returnPset.y=circle.y;
    				return ;
    			}
    			
    			returnPset.x=pset.x+ circle.r;
    			returnPset.y=pset.y+circle.r;
    			return;	
    		}
    		returnPset.x=circle.x+dx*circle.r/dz;
    		returnPset.y=circle.y+dy*circle.r/dz;
    	}
    	static int intersection(Circle circle0,Circle circle1,Pset first,Pset second) 
    	{
    		double x0,y0;
    		double d;
    		double a;
    		double h;
    
    		d=circle0.distanceTo(circle1);
    		
    		double deltaX=circle1.x - circle0.x;
    		double deltaY=circle1.y - circle0.y;
    		
    		if(d >= circle0.r+circle1.r) {
    			first.x = circle0.x+deltaX*circle0.r/(circle0.r+circle1.r);
    			first.y = circle0.y+deltaY*circle0.r/(circle0.r+circle1.r);
    			return 1; 
    		}
    		if(d <= abs(circle0.r-circle1.r)) { 
    			deltaX/=d;
    			deltaY/=d;
    			if(circle1.r<circle0.r){
    				first.x = (circle0.x+deltaX*circle0.r   +  circle1.x+deltaX*circle1.r)/2;
    				first.y = (circle0.y+deltaY*circle0.r   +  circle1.y+deltaY*circle1.r)/2;
    			}else{
    				first.x = (circle0.x-deltaX*circle0.r   +  circle1.x-deltaX*circle1.r)/2;
    				first.y = (circle0.y-deltaY*circle0.r   +  circle1.y-deltaY*circle1.r)/2;
    			}
    				
    			return 1;
    		}
    
    		a= (pow2(circle0.r) - pow2(circle1.r) + d*d ) / (2*d);
    		h= sqrt( pow2(circle0.r) - pow2(a));
    
    		x0 = circle0.x + a*deltaX / d;
    		y0 = circle0.y + a*deltaY / d;
    
    		first.x= x0 + h*deltaY / d;
    		first.y= y0 - h*deltaX / d;
    		//if(a == circle0.r ) return 1;
    		second.x= x0 - h*deltaY / d;
    		second.y= y0 + h*deltaX / d;
    		return 2;
    	}
    }
    class Pset{
    	double x;
    	double y;
    	Pset(){
    	}
    	Pset(double xx,double yy){
    		x=xx;
    		y=yy;
    	}
    	double distanceTo(Pset p){
    		return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));
    	}
    	void print(){
    		System.out.println(""+x+" "+y);
    	}
    	void printDlta(Pset answer){
    		System.out.println(""+(x-answer.x)+" "+(y-answer.y)+" "+Math.sqrt((x-answer.x)*(x-answer.x)+(y-answer.y)*(y-answer.y)));
    	}
    
    }
    class Circle extends Pset{
    	double r;
    	Circle(double xx,double yy){
    		super(xx,yy);
    	}
    	Circle(double xx,double yy,double rr){
    		super(xx,yy);
    		this.r=rr;
    	}
    }
    

С полной таблицей результатов можно ознакомится тут. Красным подсвечены результаты, выходящие за допустимые пределы (ошибка более 1000 метров, или время работы более 5 секунд. ). Скачать все решения, их ответы и результаты компиляции — можно тут. В верхней части таблицы все еще есть read-only пользователи, исправляем: ibessonov, where-is-s, Leng, Kofko, shuternay, wSpirit, dimka-74.
Читать дальше →